Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source3/libsmb/namequery.c

    r414 r745  
    2020
    2121#include "includes.h"
     22#include "../lib/util/tevent_ntstatus.h"
     23#include "libads/sitename_cache.h"
     24#include "libads/dns.h"
     25#include "../libcli/netlogon/netlogon.h"
     26#include "lib/async_req/async_sock.h"
     27#include "libsmb/nmblib.h"
    2228
    2329/* nmbd.c sets this to True. */
     
    209215****************************************************************************/
    210216
    211 static NODE_STATUS_STRUCT *parse_node_status(char *p,
     217static struct node_status *parse_node_status(TALLOC_CTX *mem_ctx, char *p,
    212218                                int *num_names,
    213219                                struct node_status_extra *extra)
    214220{
    215         NODE_STATUS_STRUCT *ret;
     221        struct node_status *ret;
    216222        int i;
    217223
     
    221227                return NULL;
    222228
    223         ret = SMB_MALLOC_ARRAY(NODE_STATUS_STRUCT,*num_names);
     229        ret = TALLOC_ARRAY(mem_ctx, struct node_status,*num_names);
    224230        if (!ret)
    225231                return NULL;
     
    244250}
    245251
     252struct sock_packet_read_state {
     253        struct tevent_context *ev;
     254        enum packet_type type;
     255        int trn_id;
     256
     257        struct nb_packet_reader *reader;
     258        struct tevent_req *reader_req;
     259
     260        int sock;
     261        struct tevent_req *socket_req;
     262        uint8_t buf[1024];
     263        struct sockaddr_storage addr;
     264        socklen_t addr_len;
     265
     266        bool (*validator)(struct packet_struct *p,
     267                          void *private_data);
     268        void *private_data;
     269
     270        struct packet_struct *packet;
     271};
     272
     273static int sock_packet_read_state_destructor(struct sock_packet_read_state *s);
     274static void sock_packet_read_got_packet(struct tevent_req *subreq);
     275static void sock_packet_read_got_socket(struct tevent_req *subreq);
     276
     277static struct tevent_req *sock_packet_read_send(
     278        TALLOC_CTX *mem_ctx,
     279        struct tevent_context *ev,
     280        int sock, /* dgram socket */
     281        struct nb_packet_reader *reader,
     282        enum packet_type type,
     283        int trn_id,
     284        bool (*validator)(struct packet_struct *p, void *private_data),
     285        void *private_data)
     286{
     287        struct tevent_req *req;
     288        struct sock_packet_read_state *state;
     289
     290        req = tevent_req_create(mem_ctx, &state,
     291                                struct sock_packet_read_state);
     292        if (req == NULL) {
     293                return NULL;
     294        }
     295        talloc_set_destructor(state, sock_packet_read_state_destructor);
     296        state->ev = ev;
     297        state->reader = reader;
     298        state->sock = sock;
     299        state->type = type;
     300        state->trn_id = trn_id;
     301        state->validator = validator;
     302        state->private_data = private_data;
     303
     304        if (reader != NULL) {
     305                state->reader_req = nb_packet_read_send(state, ev, reader);
     306                if (tevent_req_nomem(state->reader_req, req)) {
     307                        return tevent_req_post(req, ev);
     308                }
     309                tevent_req_set_callback(
     310                        state->reader_req, sock_packet_read_got_packet, req);
     311        }
     312
     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);
     317        if (tevent_req_nomem(state->socket_req, req)) {
     318                return tevent_req_post(req, ev);
     319        }
     320        tevent_req_set_callback(state->socket_req, sock_packet_read_got_socket,
     321                                req);
     322
     323        return req;
     324}
     325
     326static int sock_packet_read_state_destructor(struct sock_packet_read_state *s)
     327{
     328        if (s->packet != NULL) {
     329                free_packet(s->packet);
     330                s->packet = NULL;
     331        }
     332        return 0;
     333}
     334
     335static void sock_packet_read_got_packet(struct tevent_req *subreq)
     336{
     337        struct tevent_req *req = tevent_req_callback_data(
     338                subreq, struct tevent_req);
     339        struct sock_packet_read_state *state = tevent_req_data(
     340                req, struct sock_packet_read_state);
     341        NTSTATUS status;
     342
     343        status = nb_packet_read_recv(subreq, &state->packet);
     344
     345        TALLOC_FREE(state->reader_req);
     346
     347        if (!NT_STATUS_IS_OK(status)) {
     348                if (state->socket_req != NULL) {
     349                        /*
     350                         * Still waiting for socket
     351                         */
     352                        return;
     353                }
     354                /*
     355                 * Both socket and packet reader failed
     356                 */
     357                tevent_req_nterror(req, status);
     358                return;
     359        }
     360
     361        if ((state->validator != NULL) &&
     362            !state->validator(state->packet, state->private_data)) {
     363                DEBUG(10, ("validator failed\n"));
     364
     365                free_packet(state->packet);
     366                state->packet = NULL;
     367
     368                state->reader_req = nb_packet_read_send(state, state->ev,
     369                                                        state->reader);
     370                if (tevent_req_nomem(state->reader_req, req)) {
     371                        return;
     372                }
     373                tevent_req_set_callback(
     374                        state->reader_req, sock_packet_read_got_packet, req);
     375                return;
     376        }
     377
     378        TALLOC_FREE(state->socket_req);
     379        tevent_req_done(req);
     380}
     381
     382static void sock_packet_read_got_socket(struct tevent_req *subreq)
     383{
     384        struct tevent_req *req = tevent_req_callback_data(
     385                subreq, struct tevent_req);
     386        struct sock_packet_read_state *state = tevent_req_data(
     387                req, struct sock_packet_read_state);
     388        struct sockaddr_in *in_addr;
     389        ssize_t received;
     390        int err;
     391
     392        received = recvfrom_recv(subreq, &err);
     393
     394        TALLOC_FREE(state->socket_req);
     395
     396        if (received == -1) {
     397                if (state->reader_req != NULL) {
     398                        /*
     399                         * Still waiting for reader
     400                         */
     401                        return;
     402                }
     403                /*
     404                 * Both socket and reader failed
     405                 */
     406                tevent_req_nterror(req, map_nt_error_from_unix(err));
     407                return;
     408        }
     409        if (state->addr.ss_family != AF_INET) {
     410                goto retry;
     411        }
     412        in_addr = (struct sockaddr_in *)(void *)&state->addr;
     413
     414        state->packet = parse_packet((char *)state->buf, received, state->type,
     415                                     in_addr->sin_addr, in_addr->sin_port);
     416        if (state->packet == NULL) {
     417                DEBUG(10, ("parse_packet failed\n"));
     418                goto retry;
     419        }
     420        if ((state->trn_id != -1) &&
     421            (state->trn_id != packet_trn_id(state->packet))) {
     422                DEBUG(10, ("Expected transaction id %d, got %d\n",
     423                           state->trn_id, packet_trn_id(state->packet)));
     424                goto retry;
     425        }
     426
     427        if ((state->validator != NULL) &&
     428            !state->validator(state->packet, state->private_data)) {
     429                DEBUG(10, ("validator failed\n"));
     430                goto retry;
     431        }
     432
     433        tevent_req_done(req);
     434        return;
     435
     436retry:
     437        if (state->packet != NULL) {
     438                free_packet(state->packet);
     439                state->packet = NULL;
     440        }
     441        state->socket_req = recvfrom_send(state, state->ev, state->sock,
     442                                          state->buf, sizeof(state->buf), 0,
     443                                          &state->addr, &state->addr_len);
     444        if (tevent_req_nomem(state->socket_req, req)) {
     445                return;
     446        }
     447        tevent_req_set_callback(state->socket_req, sock_packet_read_got_socket,
     448                                req);
     449}
     450
     451static NTSTATUS sock_packet_read_recv(struct tevent_req *req,
     452                                      struct packet_struct **ppacket)
     453{
     454        struct sock_packet_read_state *state = tevent_req_data(
     455                req, struct sock_packet_read_state);
     456        NTSTATUS status;
     457
     458        if (tevent_req_is_nterror(req, &status)) {
     459                return status;
     460        }
     461        *ppacket = state->packet;
     462        state->packet = NULL;
     463        return NT_STATUS_OK;
     464}
     465
     466struct nb_trans_state {
     467        struct tevent_context *ev;
     468        int sock;
     469        struct nb_packet_reader *reader;
     470
     471        const struct sockaddr_storage *dst_addr;
     472        uint8_t *buf;
     473        size_t buflen;
     474        enum packet_type type;
     475        int trn_id;
     476
     477        bool (*validator)(struct packet_struct *p,
     478                          void *private_data);
     479        void *private_data;
     480
     481        struct packet_struct *packet;
     482};
     483
     484static int nb_trans_state_destructor(struct nb_trans_state *s);
     485static void nb_trans_got_reader(struct tevent_req *subreq);
     486static void nb_trans_done(struct tevent_req *subreq);
     487static void nb_trans_sent(struct tevent_req *subreq);
     488static void nb_trans_send_next(struct tevent_req *subreq);
     489
     490static struct tevent_req *nb_trans_send(
     491        TALLOC_CTX *mem_ctx,
     492        struct tevent_context *ev,
     493        const struct sockaddr_storage *my_addr,
     494        const struct sockaddr_storage *dst_addr,
     495        bool bcast,
     496        uint8_t *buf, size_t buflen,
     497        enum packet_type type, int trn_id,
     498        bool (*validator)(struct packet_struct *p,
     499                          void *private_data),
     500        void *private_data)
     501{
     502        struct tevent_req *req, *subreq;
     503        struct nb_trans_state *state;
     504
     505        req = tevent_req_create(mem_ctx, &state, struct nb_trans_state);
     506        if (req == NULL) {
     507                return NULL;
     508        }
     509        talloc_set_destructor(state, nb_trans_state_destructor);
     510        state->ev = ev;
     511        state->dst_addr = dst_addr;
     512        state->buf = buf;
     513        state->buflen = buflen;
     514        state->type = type;
     515        state->trn_id = trn_id;
     516        state->validator = validator;
     517        state->private_data = private_data;
     518
     519        state->sock = open_socket_in(SOCK_DGRAM, 0, 3, my_addr, True);
     520        if (state->sock == -1) {
     521                tevent_req_nterror(req, map_nt_error_from_unix(errno));
     522                DEBUG(10, ("open_socket_in failed: %s\n", strerror(errno)));
     523                return tevent_req_post(req, ev);
     524        }
     525
     526        if (bcast) {
     527                set_socket_options(state->sock,"SO_BROADCAST");
     528        }
     529
     530        subreq = nb_packet_reader_send(state, ev, type, state->trn_id, NULL);
     531        if (tevent_req_nomem(subreq, req)) {
     532                return tevent_req_post(req, ev);
     533        }
     534        tevent_req_set_callback(subreq, nb_trans_got_reader, req);
     535        return req;
     536}
     537
     538static int nb_trans_state_destructor(struct nb_trans_state *s)
     539{
     540        if (s->sock != -1) {
     541                close(s->sock);
     542                s->sock = -1;
     543        }
     544        if (s->packet != NULL) {
     545                free_packet(s->packet);
     546                s->packet = NULL;
     547        }
     548        return 0;
     549}
     550
     551static void nb_trans_got_reader(struct tevent_req *subreq)
     552{
     553        struct tevent_req *req = tevent_req_callback_data(
     554                subreq, struct tevent_req);
     555        struct nb_trans_state *state = tevent_req_data(
     556                req, struct nb_trans_state);
     557        NTSTATUS status;
     558
     559        status = nb_packet_reader_recv(subreq, state, &state->reader);
     560        TALLOC_FREE(subreq);
     561
     562        if (!NT_STATUS_IS_OK(status)) {
     563                DEBUG(10, ("nmbd not around\n"));
     564                state->reader = NULL;
     565        }
     566
     567        subreq = sock_packet_read_send(
     568                state, state->ev, state->sock,
     569                state->reader, state->type, state->trn_id,
     570                state->validator, state->private_data);
     571        if (tevent_req_nomem(subreq, req)) {
     572                return;
     573        }
     574        tevent_req_set_callback(subreq, nb_trans_done, req);
     575
     576        subreq = sendto_send(state, state->ev, state->sock,
     577                             state->buf, state->buflen, 0, state->dst_addr);
     578        if (tevent_req_nomem(subreq, req)) {
     579                return;
     580        }
     581        tevent_req_set_callback(subreq, nb_trans_sent, req);
     582}
     583
     584static void nb_trans_sent(struct tevent_req *subreq)
     585{
     586        struct tevent_req *req = tevent_req_callback_data(
     587                subreq, struct tevent_req);
     588        struct nb_trans_state *state = tevent_req_data(
     589                req, struct nb_trans_state);
     590        ssize_t sent;
     591        int err;
     592
     593        sent = sendto_recv(subreq, &err);
     594        TALLOC_FREE(subreq);
     595        if (sent == -1) {
     596                DEBUG(10, ("sendto failed: %s\n", strerror(err)));
     597                tevent_req_nterror(req, map_nt_error_from_unix(err));
     598                return;
     599        }
     600        subreq = tevent_wakeup_send(state, state->ev,
     601                                    timeval_current_ofs(1, 0));
     602        if (tevent_req_nomem(subreq, req)) {
     603                return;
     604        }
     605        tevent_req_set_callback(subreq, nb_trans_send_next, req);
     606}
     607
     608static void nb_trans_send_next(struct tevent_req *subreq)
     609{
     610        struct tevent_req *req = tevent_req_callback_data(
     611                subreq, struct tevent_req);
     612        struct nb_trans_state *state = tevent_req_data(
     613                req, struct nb_trans_state);
     614        bool ret;
     615
     616        ret = tevent_wakeup_recv(subreq);
     617        TALLOC_FREE(subreq);
     618        if (!ret) {
     619                tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
     620                return;
     621        }
     622        subreq = sendto_send(state, state->ev, state->sock,
     623                             state->buf, state->buflen, 0, state->dst_addr);
     624        if (tevent_req_nomem(subreq, req)) {
     625                return;
     626        }
     627        tevent_req_set_callback(subreq, nb_trans_sent, req);
     628}
     629
     630static void nb_trans_done(struct tevent_req *subreq)
     631{
     632        struct tevent_req *req = tevent_req_callback_data(
     633                subreq, struct tevent_req);
     634        struct nb_trans_state *state = tevent_req_data(
     635                req, struct nb_trans_state);
     636        NTSTATUS status;
     637
     638        status = sock_packet_read_recv(subreq, &state->packet);
     639        TALLOC_FREE(subreq);
     640        if (tevent_req_nterror(req, status)) {
     641                return;
     642        }
     643        tevent_req_done(req);
     644}
     645
     646static NTSTATUS nb_trans_recv(struct tevent_req *req,
     647                              struct packet_struct **ppacket)
     648{
     649        struct nb_trans_state *state = tevent_req_data(
     650                req, struct nb_trans_state);
     651        NTSTATUS status;
     652
     653        if (tevent_req_is_nterror(req, &status)) {
     654                return status;
     655        }
     656        *ppacket = state->packet;
     657        state->packet = NULL;
     658        return NT_STATUS_OK;
     659}
    246660
    247661/****************************************************************************
     
    250664**************************************************************************/
    251665
    252 NODE_STATUS_STRUCT *node_status_query(int fd,
    253                                         struct nmb_name *name,
    254                                         const struct sockaddr_storage *to_ss,
    255                                         int *num_names,
    256                                         struct node_status_extra *extra)
    257 {
    258         bool found=False;
    259         int retries = 2;
    260         int retry_time = 2000;
    261         struct timeval tval;
     666struct node_status_query_state {
     667        struct sockaddr_storage my_addr;
     668        struct sockaddr_storage addr;
     669        uint8_t buf[1024];
     670        ssize_t buflen;
     671        struct packet_struct *packet;
     672};
     673
     674static int node_status_query_state_destructor(
     675        struct node_status_query_state *s);
     676static bool node_status_query_validator(struct packet_struct *p,
     677                                        void *private_data);
     678static void node_status_query_done(struct tevent_req *subreq);
     679
     680struct tevent_req *node_status_query_send(TALLOC_CTX *mem_ctx,
     681                                          struct tevent_context *ev,
     682                                          struct nmb_name *name,
     683                                          const struct sockaddr_storage *addr)
     684{
     685        struct tevent_req *req, *subreq;
     686        struct node_status_query_state *state;
    262687        struct packet_struct p;
    263         struct packet_struct *p2;
    264688        struct nmb_packet *nmb = &p.packet.nmb;
    265         NODE_STATUS_STRUCT *ret;
     689        struct sockaddr_in *in_addr;
     690
     691        req = tevent_req_create(mem_ctx, &state,
     692                                struct node_status_query_state);
     693        if (req == NULL) {
     694                return NULL;
     695        }
     696        talloc_set_destructor(state, node_status_query_state_destructor);
     697
     698        if (addr->ss_family != AF_INET) {
     699                /* Can't do node status to IPv6 */
     700                tevent_req_nterror(req, NT_STATUS_INVALID_ADDRESS);
     701                return tevent_req_post(req, ev);
     702        }
     703
     704        state->addr = *addr;
     705        in_addr = (struct sockaddr_in *)(void *)&state->addr;
     706        in_addr->sin_port = htons(NMB_PORT);
     707
     708        if (!interpret_string_addr(&state->my_addr, lp_socket_address(),
     709                                   AI_NUMERICHOST|AI_PASSIVE)) {
     710                zero_sockaddr(&state->my_addr);
     711        }
    266712
    267713        ZERO_STRUCT(p);
    268 
    269         if (to_ss->ss_family != AF_INET) {
    270                 /* Can't do node status to IPv6 */
    271                 return NULL;
    272         }
    273714        nmb->header.name_trn_id = generate_trn_id();
    274715        nmb->header.opcode = 0;
     
    288729        nmb->question.question_class = 0x1;
    289730
    290         p.ip = ((const struct sockaddr_in *)to_ss)->sin_addr;
    291         p.port = NMB_PORT;
    292         p.recv_fd = -1;
    293         p.send_fd = fd;
    294         p.timestamp = time(NULL);
    295         p.packet_type = NMB_PACKET;
    296 
    297         GetTimeOfDay(&tval);
    298 
    299         if (!send_packet(&p))
    300                 return NULL;
    301 
    302         retries--;
    303 
    304         while (1) {
    305                 struct timeval tval2;
    306                 GetTimeOfDay(&tval2);
    307                 if (TvalDiff(&tval,&tval2) > retry_time) {
    308                         if (!retries)
    309                                 break;
    310                         if (!found && !send_packet(&p))
    311                                 return NULL;
    312                         GetTimeOfDay(&tval);
    313                         retries--;
    314                 }
    315 
    316                 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
    317                         struct nmb_packet *nmb2 = &p2->packet.nmb;
    318                         debug_nmb_packet(p2);
    319 
    320                         if (nmb2->header.opcode != 0 ||
    321                             nmb2->header.nm_flags.bcast ||
    322                             nmb2->header.rcode ||
    323                             !nmb2->header.ancount ||
    324                             nmb2->answers->rr_type != 0x21) {
    325                                 /* XXXX what do we do with this? could be a
    326                                    redirect, but we'll discard it for the
    327                                    moment */
    328                                 free_packet(p2);
    329                                 continue;
    330                         }
    331 
    332                         ret = parse_node_status(&nmb2->answers->rdata[0],
    333                                         num_names, extra);
    334                         free_packet(p2);
    335                         return ret;
    336                 }
    337         }
    338 
    339         return NULL;
     731        state->buflen = build_packet((char *)state->buf, sizeof(state->buf),
     732                                     &p);
     733        if (state->buflen == 0) {
     734                tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
     735                DEBUG(10, ("build_packet failed\n"));
     736                return tevent_req_post(req, ev);
     737        }
     738
     739        subreq = nb_trans_send(state, ev, &state->my_addr, &state->addr, false,
     740                               state->buf, state->buflen,
     741                               NMB_PACKET, nmb->header.name_trn_id,
     742                               node_status_query_validator, NULL);
     743        if (tevent_req_nomem(subreq, req)) {
     744                DEBUG(10, ("nb_trans_send failed\n"));
     745                return tevent_req_post(req, ev);
     746        }
     747        if (!tevent_req_set_endtime(req, ev, timeval_current_ofs(10, 0))) {
     748                return tevent_req_post(req, ev);
     749        }
     750        tevent_req_set_callback(subreq, node_status_query_done, req);
     751        return req;
     752}
     753
     754static bool node_status_query_validator(struct packet_struct *p,
     755                                        void *private_data)
     756{
     757        struct nmb_packet *nmb = &p->packet.nmb;
     758        debug_nmb_packet(p);
     759
     760        if (nmb->header.opcode != 0 ||
     761            nmb->header.nm_flags.bcast ||
     762            nmb->header.rcode ||
     763            !nmb->header.ancount ||
     764            nmb->answers->rr_type != 0x21) {
     765                /*
     766                 * XXXX what do we do with this? could be a redirect,
     767                 * but we'll discard it for the moment
     768                 */
     769                return false;
     770        }
     771        return true;
     772}
     773
     774static int node_status_query_state_destructor(
     775        struct node_status_query_state *s)
     776{
     777        if (s->packet != NULL) {
     778                free_packet(s->packet);
     779                s->packet = NULL;
     780        }
     781        return 0;
     782}
     783
     784static void node_status_query_done(struct tevent_req *subreq)
     785{
     786        struct tevent_req *req = tevent_req_callback_data(
     787                subreq, struct tevent_req);
     788        struct node_status_query_state *state = tevent_req_data(
     789                req, struct node_status_query_state);
     790        NTSTATUS status;
     791
     792        status = nb_trans_recv(subreq, &state->packet);
     793        TALLOC_FREE(subreq);
     794        if (tevent_req_nterror(req, status)) {
     795                return;
     796        }
     797        tevent_req_done(req);
     798}
     799
     800NTSTATUS node_status_query_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
     801                                struct node_status **pnode_status,
     802                                int *pnum_names,
     803                                struct node_status_extra *extra)
     804{
     805        struct node_status_query_state *state = tevent_req_data(
     806                req, struct node_status_query_state);
     807        struct node_status *node_status;
     808        int num_names;
     809        NTSTATUS status;
     810
     811        if (tevent_req_is_nterror(req, &status)) {
     812                return status;
     813        }
     814        node_status = parse_node_status(
     815                mem_ctx, &state->packet->packet.nmb.answers->rdata[0],
     816                &num_names, extra);
     817        if (node_status == NULL) {
     818                return NT_STATUS_NO_MEMORY;
     819        }
     820        *pnode_status = node_status;
     821        *pnum_names = num_names;
     822        return NT_STATUS_OK;
     823}
     824
     825NTSTATUS node_status_query(TALLOC_CTX *mem_ctx, struct nmb_name *name,
     826                           const struct sockaddr_storage *addr,
     827                           struct node_status **pnode_status,
     828                           int *pnum_names,
     829                           struct node_status_extra *extra)
     830{
     831        TALLOC_CTX *frame = talloc_stackframe();
     832        struct tevent_context *ev;
     833        struct tevent_req *req;
     834        NTSTATUS status = NT_STATUS_NO_MEMORY;
     835
     836        ev = tevent_context_init(frame);
     837        if (ev == NULL) {
     838                goto fail;
     839        }
     840        req = node_status_query_send(ev, ev, name, addr);
     841        if (req == NULL) {
     842                goto fail;
     843        }
     844        if (!tevent_req_poll_ntstatus(req, ev, &status)) {
     845                goto fail;
     846        }
     847        status = node_status_query_recv(req, mem_ctx, pnode_status,
     848                                        pnum_names, extra);
     849 fail:
     850        TALLOC_FREE(frame);
     851        return status;
    340852}
    341853
     
    353865        char addr[INET6_ADDRSTRLEN];
    354866        struct sockaddr_storage ss;
    355         NODE_STATUS_STRUCT *status = NULL;
     867        struct node_status *addrs = NULL;
    356868        struct nmb_name nname;
    357869        int count, i;
    358         int sock;
    359870        bool result = false;
     871        NTSTATUS status;
    360872
    361873        if (lp_disable_netbios()) {
     
    386898        }
    387899
    388         sock = open_socket_in(SOCK_DGRAM, 0, 3, &ss, True);
    389         if (sock == -1)
    390                 goto done;
    391 
    392900        /* W2K PDC's seem not to respond to '*'#0. JRA */
    393901        make_nmb_name(&nname, q_name, q_type);
    394         status = node_status_query(sock, &nname, to_ss, &count, NULL);
    395         close(sock);
    396         if (!status)
     902        status = node_status_query(talloc_tos(), &nname, to_ss,
     903                                   &addrs, &count, NULL);
     904        if (!NT_STATUS_IS_OK(status)) {
    397905                goto done;
     906        }
    398907
    399908        for (i=0;i<count;i++) {
    400909                /* Find first one of the requested type that's not a GROUP. */
    401                 if (status[i].type == type && ! (status[i].flags & 0x80))
     910                if (addrs[i].type == type && ! (addrs[i].flags & 0x80))
    402911                        break;
    403912        }
     
    405914                goto done;
    406915
    407         pull_ascii_nstring(name, sizeof(fstring), status[i].name);
     916        pull_ascii_nstring(name, sizeof(fstring), addrs[i].name);
    408917
    409918        /* Store the result in the cache. */
     
    418927
    419928 done:
    420         SAFE_FREE(status);
     929        TALLOC_FREE(addrs);
    421930
    422931        DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not "));
     
    434943*/
    435944
    436 static int addr_compare(const struct sockaddr *ss1,
    437                 const struct sockaddr *ss2)
     945static int addr_compare(const struct sockaddr_storage *ss1,
     946                        const struct sockaddr_storage *ss2)
    438947{
    439948        int max_bits1=0, max_bits2=0;
     
    442951
    443952        /* Sort IPv4 addresses first. */
    444         if (ss1->sa_family != ss2->sa_family) {
    445                 if (ss2->sa_family == AF_INET) {
     953        if (ss1->ss_family != ss2->ss_family) {
     954                if (ss2->ss_family == AF_INET) {
    446955                        return 1;
    447956                } else {
     
    461970                int bits1, bits2;
    462971
    463                 if (pss->ss_family != ss1->sa_family) {
     972                if (pss->ss_family != ss1->ss_family) {
    464973                        /* Ignore interfaces of the wrong type. */
    465974                        continue;
     
    4951004
    4961005        /* Bias towards directly reachable IPs */
    497         if (iface_local(ss1)) {
    498                 if (ss1->sa_family == AF_INET) {
     1006        if (iface_local((struct sockaddr *)ss1)) {
     1007                if (ss1->ss_family == AF_INET) {
    4991008                        max_bits1 += 32;
    5001009                } else {
     
    5021011                }
    5031012        }
    504         if (iface_local(ss2)) {
    505                 if (ss2->sa_family == AF_INET) {
     1013        if (iface_local((struct sockaddr *)ss2)) {
     1014                if (ss2->ss_family == AF_INET) {
    5061015                        max_bits2 += 32;
    5071016                } else {
     
    5201029        int result;
    5211030
    522         if ((result = addr_compare((struct sockaddr *)&ss1->ss, (struct sockaddr *)&ss2->ss)) != 0) {
     1031        if ((result = addr_compare(&ss1->ss, &ss2->ss)) != 0) {
    5231032                return result;
    5241033        }
     
    5471056        }
    5481057
    549         qsort(sslist, count, sizeof(struct sockaddr_storage),
    550                         QSORT_CAST addr_compare);
     1058        TYPESAFE_QSORT(sslist, count, addr_compare);
    5511059}
    5521060
     
    5571065        }
    5581066
    559         qsort(servlist, count, sizeof(struct ip_service),
    560                         QSORT_CAST ip_service_compare);
     1067        TYPESAFE_QSORT(servlist, count, ip_service_compare);
    5611068}
    5621069
     
    5741081        /* one loop to remove duplicates */
    5751082        for ( i=0; i<count; i++ ) {
    576                 if ( is_zero_addr((struct sockaddr *)&iplist[i].ss)) {
     1083                if ( is_zero_addr(&iplist[i].ss)) {
    5771084                        continue;
    5781085                }
     
    5891096        /* first ip should never be a zero_ip() */
    5901097        for (i = 0; i<count; ) {
    591                 if (is_zero_addr((struct sockaddr *)&iplist[i].ss) ) {
     1098                if (is_zero_addr(&iplist[i].ss) ) {
    5921099                        if (i != count-1) {
    5931100                                memmove(&iplist[i], &iplist[i+1],
     
    6421149****************************************************************************/
    6431150
    644 struct sockaddr_storage *name_query(int fd,
    645                         const char *name,
    646                         int name_type,
    647                         bool bcast,
    648                         bool recurse,
    649                         const struct sockaddr_storage *to_ss,
    650                         int *count,
    651                         int *flags,
    652                         bool *timed_out)
    653 {
    654         bool found=false;
    655         int i, retries = 3;
    656         int retry_time = bcast?250:2000;
    657         struct timeval tval;
     1151struct name_query_state {
     1152        struct sockaddr_storage my_addr;
     1153        struct sockaddr_storage addr;
     1154        bool bcast;
     1155
     1156
     1157        uint8_t buf[1024];
     1158        ssize_t buflen;
     1159
     1160        NTSTATUS validate_error;
     1161        uint8_t flags;
     1162
     1163        struct sockaddr_storage *addrs;
     1164        int num_addrs;
     1165};
     1166
     1167static bool name_query_validator(struct packet_struct *p, void *private_data);
     1168static void name_query_done(struct tevent_req *subreq);
     1169
     1170struct tevent_req *name_query_send(TALLOC_CTX *mem_ctx,
     1171                                   struct tevent_context *ev,
     1172                                   const char *name, int name_type,
     1173                                   bool bcast, bool recurse,
     1174                                   const struct sockaddr_storage *addr)
     1175{
     1176        struct tevent_req *req, *subreq;
     1177        struct name_query_state *state;
    6581178        struct packet_struct p;
    659         struct packet_struct *p2;
    6601179        struct nmb_packet *nmb = &p.packet.nmb;
    661         struct sockaddr_storage *ss_list = NULL;
     1180        struct sockaddr_in *in_addr;
     1181
     1182        req = tevent_req_create(mem_ctx, &state, struct name_query_state);
     1183        if (req == NULL) {
     1184                return NULL;
     1185        }
     1186        state->bcast = bcast;
     1187
     1188        if (addr->ss_family != AF_INET) {
     1189                /* Can't do node status to IPv6 */
     1190                tevent_req_nterror(req, NT_STATUS_INVALID_ADDRESS);
     1191                return tevent_req_post(req, ev);
     1192        }
    6621193
    6631194        if (lp_disable_netbios()) {
    6641195                DEBUG(5,("name_query(%s#%02x): netbios is disabled\n",
    6651196                                        name, name_type));
    666                 return NULL;
    667         }
    668 
    669         if (to_ss->ss_family != AF_INET) {
    670                 return NULL;
    671         }
    672 
    673         if (timed_out) {
    674                 *timed_out = false;
    675         }
    676 
    677         memset((char *)&p,'\0',sizeof(p));
    678         (*count) = 0;
    679         (*flags) = 0;
    680 
     1197                tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
     1198                return tevent_req_post(req, ev);
     1199        }
     1200
     1201        state->addr = *addr;
     1202        in_addr = (struct sockaddr_in *)(void *)&state->addr;
     1203        in_addr->sin_port = htons(NMB_PORT);
     1204
     1205        if (!interpret_string_addr(&state->my_addr, lp_socket_address(),
     1206                                   AI_NUMERICHOST|AI_PASSIVE)) {
     1207                zero_sockaddr(&state->my_addr);
     1208        }
     1209
     1210        ZERO_STRUCT(p);
    6811211        nmb->header.name_trn_id = generate_trn_id();
    6821212        nmb->header.opcode = 0;
     
    6981228        nmb->question.question_class = 0x1;
    6991229
    700         p.ip = ((struct sockaddr_in *)to_ss)->sin_addr;
    701         p.port = NMB_PORT;
    702         p.recv_fd = -1;
    703         p.send_fd = fd;
    704         p.timestamp = time(NULL);
    705         p.packet_type = NMB_PACKET;
    706 
    707         GetTimeOfDay(&tval);
    708 
    709         if (!send_packet(&p))
    710                 return NULL;
    711 
    712         retries--;
    713 
    714         while (1) {
    715                 struct timeval tval2;
    716 
    717                 GetTimeOfDay(&tval2);
    718                 if (TvalDiff(&tval,&tval2) > retry_time) {
    719                         if (!retries)
     1230        state->buflen = build_packet((char *)state->buf, sizeof(state->buf),
     1231                                     &p);
     1232        if (state->buflen == 0) {
     1233                tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
     1234                DEBUG(10, ("build_packet failed\n"));
     1235                return tevent_req_post(req, ev);
     1236        }
     1237
     1238        subreq = nb_trans_send(state, ev, &state->my_addr, &state->addr, bcast,
     1239                               state->buf, state->buflen,
     1240                               NMB_PACKET, nmb->header.name_trn_id,
     1241                               name_query_validator, state);
     1242        if (tevent_req_nomem(subreq, req)) {
     1243                DEBUG(10, ("nb_trans_send failed\n"));
     1244                return tevent_req_post(req, ev);
     1245        }
     1246        tevent_req_set_callback(subreq, name_query_done, req);
     1247        return req;
     1248}
     1249
     1250static bool name_query_validator(struct packet_struct *p, void *private_data)
     1251{
     1252        struct name_query_state *state = talloc_get_type_abort(
     1253                private_data, struct name_query_state);
     1254        struct nmb_packet *nmb = &p->packet.nmb;
     1255        struct sockaddr_storage *tmp_addrs;
     1256        bool got_unique_netbios_name = false;
     1257        int i;
     1258
     1259        debug_nmb_packet(p);
     1260
     1261        /*
     1262         * If we get a Negative Name Query Response from a WINS
     1263         * server, we should report it and give up.
     1264         */
     1265        if( 0 == nmb->header.opcode     /* A query response   */
     1266            && !state->bcast            /* from a WINS server */
     1267            && nmb->header.rcode        /* Error returned     */
     1268                ) {
     1269
     1270                if( DEBUGLVL( 3 ) ) {
     1271                        /* Only executed if DEBUGLEVEL >= 3 */
     1272                        dbgtext( "Negative name query "
     1273                                 "response, rcode 0x%02x: ",
     1274                                 nmb->header.rcode );
     1275                        switch( nmb->header.rcode ) {
     1276                        case 0x01:
     1277                                dbgtext("Request was invalidly formatted.\n");
    7201278                                break;
    721                         if (!found && !send_packet(&p))
    722                                 return NULL;
    723                         GetTimeOfDay(&tval);
    724                         retries--;
    725                 }
    726 
    727                 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
    728                         struct nmb_packet *nmb2 = &p2->packet.nmb;
    729                         debug_nmb_packet(p2);
    730 
    731                         /* If we get a Negative Name Query Response from a WINS
    732                          * server, we should report it and give up.
    733                          */
    734                         if( 0 == nmb2->header.opcode    /* A query response   */
    735                             && !(bcast)                 /* from a WINS server */
    736                             && nmb2->header.rcode       /* Error returned     */
    737                                 ) {
    738 
    739                                 if( DEBUGLVL( 3 ) ) {
    740                                         /* Only executed if DEBUGLEVEL >= 3 */
    741                                         dbgtext( "Negative name query "
    742                                                 "response, rcode 0x%02x: ",
    743                                                 nmb2->header.rcode );
    744                                         switch( nmb2->header.rcode ) {
    745                                         case 0x01:
    746                                                 dbgtext( "Request "
    747                                                 "was invalidly formatted.\n" );
    748                                                 break;
    749                                         case 0x02:
    750                                                 dbgtext( "Problem with NBNS, "
    751                                                 "cannot process name.\n");
    752                                                 break;
    753                                         case 0x03:
    754                                                 dbgtext( "The name requested "
    755                                                 "does not exist.\n" );
    756                                                 break;
    757                                         case 0x04:
    758                                                 dbgtext( "Unsupported request "
    759                                                 "error.\n" );
    760                                                 break;
    761                                         case 0x05:
    762                                                 dbgtext( "Query refused "
    763                                                 "error.\n" );
    764                                                 break;
    765                                         default:
    766                                                 dbgtext( "Unrecognized error "
    767                                                 "code.\n" );
    768                                                 break;
    769                                         }
    770                                 }
    771                                 free_packet(p2);
    772                                 return( NULL );
     1279                        case 0x02:
     1280                                dbgtext("Problem with NBNS, cannot process "
     1281                                        "name.\n");
     1282                                break;
     1283                        case 0x03:
     1284                                dbgtext("The name requested does not "
     1285                                        "exist.\n");
     1286                                break;
     1287                        case 0x04:
     1288                                dbgtext("Unsupported request error.\n");
     1289                                break;
     1290                        case 0x05:
     1291                                dbgtext("Query refused error.\n");
     1292                                break;
     1293                        default:
     1294                                dbgtext("Unrecognized error code.\n" );
     1295                                break;
    7731296                        }
    774 
    775                         if (nmb2->header.opcode != 0 ||
    776                             nmb2->header.nm_flags.bcast ||
    777                             nmb2->header.rcode ||
    778                             !nmb2->header.ancount) {
    779                                 /*
    780                                  * XXXX what do we do with this? Could be a
    781                                  * redirect, but we'll discard it for the
    782                                  * moment.
    783                                  */
    784                                 free_packet(p2);
    785                                 continue;
     1297                }
     1298
     1299                /*
     1300                 * We accept this packet as valid, but tell the upper
     1301                 * layers that it's a negative response.
     1302                 */
     1303                state->validate_error = NT_STATUS_NOT_FOUND;
     1304                return true;
     1305        }
     1306
     1307        if (nmb->header.opcode != 0 ||
     1308            nmb->header.nm_flags.bcast ||
     1309            nmb->header.rcode ||
     1310            !nmb->header.ancount) {
     1311                /*
     1312                 * XXXX what do we do with this? Could be a redirect,
     1313                 * but we'll discard it for the moment.
     1314                 */
     1315                return false;
     1316        }
     1317
     1318        tmp_addrs = TALLOC_REALLOC_ARRAY(
     1319                state, state->addrs, struct sockaddr_storage,
     1320                state->num_addrs + nmb->answers->rdlength/6);
     1321        if (tmp_addrs == NULL) {
     1322                state->validate_error = NT_STATUS_NO_MEMORY;
     1323                return true;
     1324        }
     1325        state->addrs = tmp_addrs;
     1326
     1327        DEBUG(2,("Got a positive name query response "
     1328                 "from %s ( ", inet_ntoa(p->ip)));
     1329
     1330        for (i=0; i<nmb->answers->rdlength/6; i++) {
     1331                uint16_t flags;
     1332                struct in_addr ip;
     1333                struct sockaddr_storage addr;
     1334                int j;
     1335
     1336                flags = RSVAL(&nmb->answers->rdata[i*6], 0);
     1337                got_unique_netbios_name |= ((flags & 0x8000) == 0);
     1338
     1339                putip((char *)&ip,&nmb->answers->rdata[2+i*6]);
     1340                in_addr_to_sockaddr_storage(&addr, ip);
     1341
     1342                for (j=0; j<state->num_addrs; j++) {
     1343                        if (sockaddr_equal(
     1344                                    (struct sockaddr *)&addr,
     1345                                    (struct sockaddr *)&state->addrs[j])) {
     1346                                break;
    7861347                        }
    787 
    788                         ss_list = SMB_REALLOC_ARRAY(ss_list,
    789                                                 struct sockaddr_storage,
    790                                                 (*count) +
    791                                                 nmb2->answers->rdlength/6);
    792 
    793                         if (!ss_list) {
    794                                 DEBUG(0,("name_query: Realloc failed.\n"));
    795                                 free_packet(p2);
    796                                 return NULL;
    797                         }
    798 
    799                         DEBUG(2,("Got a positive name query response "
    800                                         "from %s ( ",
    801                                         inet_ntoa(p2->ip)));
    802 
    803                         for (i=0;i<nmb2->answers->rdlength/6;i++) {
    804                                 struct in_addr ip;
    805                                 putip((char *)&ip,&nmb2->answers->rdata[2+i*6]);
    806                                 in_addr_to_sockaddr_storage(&ss_list[(*count)],
    807                                                 ip);
    808                                 DEBUGADD(2,("%s ",inet_ntoa(ip)));
    809                                 (*count)++;
    810                         }
    811                         DEBUGADD(2,(")\n"));
    812 
    813                         found=true;
    814                         retries=0;
    815                         /* We add the flags back ... */
    816                         if (nmb2->header.response)
    817                                 (*flags) |= NM_FLAGS_RS;
    818                         if (nmb2->header.nm_flags.authoritative)
    819                                 (*flags) |= NM_FLAGS_AA;
    820                         if (nmb2->header.nm_flags.trunc)
    821                                 (*flags) |= NM_FLAGS_TC;
    822                         if (nmb2->header.nm_flags.recursion_desired)
    823                                 (*flags) |= NM_FLAGS_RD;
    824                         if (nmb2->header.nm_flags.recursion_available)
    825                                 (*flags) |= NM_FLAGS_RA;
    826                         if (nmb2->header.nm_flags.bcast)
    827                                 (*flags) |= NM_FLAGS_B;
    828                         free_packet(p2);
    829                         /*
    830                          * If we're doing a unicast lookup we only
    831                          * expect one reply. Don't wait the full 2
    832                          * seconds if we got one. JRA.
    833                          */
    834                         if(!bcast && found)
    835                                 break;
    836                 }
    837         }
    838 
    839         /* only set timed_out if we didn't fund what we where looking for*/
    840 
    841         if ( !found && timed_out ) {
    842                 *timed_out = true;
    843         }
    844 
    845         /* sort the ip list so we choose close servers first if possible */
    846         sort_addr_list(ss_list, *count);
    847 
    848         return ss_list;
     1348                }
     1349                if (j < state->num_addrs) {
     1350                        /* Already got it */
     1351                        continue;
     1352                }
     1353
     1354                DEBUGADD(2,("%s ",inet_ntoa(ip)));
     1355
     1356                state->addrs[state->num_addrs] = addr;
     1357                state->num_addrs += 1;
     1358        }
     1359        DEBUGADD(2,(")\n"));
     1360
     1361        /* We add the flags back ... */
     1362        if (nmb->header.response)
     1363                state->flags |= NM_FLAGS_RS;
     1364        if (nmb->header.nm_flags.authoritative)
     1365                state->flags |= NM_FLAGS_AA;
     1366        if (nmb->header.nm_flags.trunc)
     1367                state->flags |= NM_FLAGS_TC;
     1368        if (nmb->header.nm_flags.recursion_desired)
     1369                state->flags |= NM_FLAGS_RD;
     1370        if (nmb->header.nm_flags.recursion_available)
     1371                state->flags |= NM_FLAGS_RA;
     1372        if (nmb->header.nm_flags.bcast)
     1373                state->flags |= NM_FLAGS_B;
     1374
     1375        if (state->bcast) {
     1376                /*
     1377                 * We have to collect all entries coming in from broadcast
     1378                 * queries. If we got a unique name, we're done.
     1379                 */
     1380                return got_unique_netbios_name;
     1381        }
     1382        /*
     1383         * WINS responses are accepted when they are received
     1384         */
     1385        return true;
     1386}
     1387
     1388static void name_query_done(struct tevent_req *subreq)
     1389{
     1390        struct tevent_req *req = tevent_req_callback_data(
     1391                subreq, struct tevent_req);
     1392        struct name_query_state *state = tevent_req_data(
     1393                req, struct name_query_state);
     1394        NTSTATUS status;
     1395        struct packet_struct *p = NULL;
     1396
     1397        status = nb_trans_recv(subreq, &p);
     1398        TALLOC_FREE(subreq);
     1399        if (tevent_req_nterror(req, status)) {
     1400                return;
     1401        }
     1402        if (!NT_STATUS_IS_OK(state->validate_error)) {
     1403                tevent_req_nterror(req, state->validate_error);
     1404                return;
     1405        }
     1406        if (p != NULL) {
     1407                /*
     1408                 * Free the packet here, we've collected the response in the
     1409                 * validator
     1410                 */
     1411                free_packet(p);
     1412        }
     1413        tevent_req_done(req);
     1414}
     1415
     1416NTSTATUS name_query_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
     1417                         struct sockaddr_storage **addrs, int *num_addrs,
     1418                         uint8_t *flags)
     1419{
     1420        struct name_query_state *state = tevent_req_data(
     1421                req, struct name_query_state);
     1422        NTSTATUS status;
     1423
     1424        if (tevent_req_is_nterror(req, &status)
     1425            && !NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
     1426                return status;
     1427        }
     1428        if (state->num_addrs == 0) {
     1429                return NT_STATUS_NOT_FOUND;
     1430        }
     1431        *addrs = talloc_move(mem_ctx, &state->addrs);
     1432        sort_addr_list(*addrs, state->num_addrs);
     1433        *num_addrs = state->num_addrs;
     1434        if (flags != NULL) {
     1435                *flags = state->flags;
     1436        }
     1437        return NT_STATUS_OK;
     1438}
     1439
     1440NTSTATUS name_query(const char *name, int name_type,
     1441                    bool bcast, bool recurse,
     1442                    const struct sockaddr_storage *to_ss,
     1443                    TALLOC_CTX *mem_ctx,
     1444                    struct sockaddr_storage **addrs,
     1445                    int *num_addrs, uint8_t *flags)
     1446{
     1447        TALLOC_CTX *frame = talloc_stackframe();
     1448        struct tevent_context *ev;
     1449        struct tevent_req *req;
     1450        struct timeval timeout;
     1451        NTSTATUS status = NT_STATUS_NO_MEMORY;
     1452
     1453        ev = tevent_context_init(frame);
     1454        if (ev == NULL) {
     1455                goto fail;
     1456        }
     1457        req = name_query_send(ev, ev, name, name_type, bcast, recurse, to_ss);
     1458        if (req == NULL) {
     1459                goto fail;
     1460        }
     1461        if (bcast) {
     1462                timeout = timeval_current_ofs(0, 250000);
     1463        } else {
     1464                timeout = timeval_current_ofs(2, 0);
     1465        }
     1466        if (!tevent_req_set_endtime(req, ev, timeout)) {
     1467                goto fail;
     1468        }
     1469        if (!tevent_req_poll_ntstatus(req, ev, &status)) {
     1470                goto fail;
     1471        }
     1472        status = name_query_recv(req, mem_ctx, addrs, num_addrs, flags);
     1473 fail:
     1474        TALLOC_FREE(frame);
     1475        return status;
    8491476}
    8501477
     
    8851512NTSTATUS name_resolve_bcast(const char *name,
    8861513                        int name_type,
    887                         struct ip_service **return_iplist,
     1514                        TALLOC_CTX *mem_ctx,
     1515                        struct sockaddr_storage **return_iplist,
    8881516                        int *return_count)
    8891517{
    890         int sock, i;
     1518        int i;
    8911519        int num_interfaces = iface_count();
    8921520        struct sockaddr_storage *ss_list;
    893         struct sockaddr_storage ss;
    894         NTSTATUS status;
     1521        NTSTATUS status = NT_STATUS_NOT_FOUND;
    8951522
    8961523        if (lp_disable_netbios()) {
     
    9101537                "for name %s<0x%x>\n", name, name_type));
    9111538
    912         if (!interpret_string_addr(&ss, lp_socket_address(),
    913                                 AI_NUMERICHOST|AI_PASSIVE)) {
    914                 zero_sockaddr(&ss);
    915         }
    916 
    917         sock = open_socket_in( SOCK_DGRAM, 0, 3, &ss, true );
    918         if (sock == -1) {
    919                 return NT_STATUS_UNSUCCESSFUL;
    920         }
    921 
    922         set_socket_options(sock,"SO_BROADCAST");
    9231539        /*
    9241540         * Lookup the name on all the interfaces, return on
     
    9271543        for( i = num_interfaces-1; i >= 0; i--) {
    9281544                const struct sockaddr_storage *pss = iface_n_bcast(i);
    929                 int flags;
    9301545
    9311546                /* Done this way to fix compiler error on IRIX 5.x */
     
    9331548                        continue;
    9341549                }
    935                 ss_list = name_query(sock, name, name_type, true,
    936                                     true, pss, return_count, &flags, NULL);
    937                 if (ss_list) {
     1550                status = name_query(name, name_type, true, true, pss,
     1551                                    talloc_tos(), &ss_list, return_count,
     1552                                    NULL);
     1553                if (NT_STATUS_IS_OK(status)) {
    9381554                        goto success;
    9391555                }
     
    9421558        /* failed - no response */
    9431559
    944         close(sock);
    945         return NT_STATUS_UNSUCCESSFUL;
     1560        return status;
    9461561
    9471562success:
    948 
    949         status = NT_STATUS_OK;
    950         if (!convert_ss2service(return_iplist, ss_list, *return_count) )
    951                 status = NT_STATUS_INVALID_PARAMETER;
    952 
    953         SAFE_FREE(ss_list);
    954         close(sock);
     1563        *return_iplist = ss_list;
    9551564        return status;
    9561565}
     
    9651574                int *return_count)
    9661575{
    967         int sock, t, i;
     1576        int t, i;
    9681577        char **wins_tags;
    9691578        struct sockaddr_storage src_ss, *ss_list = NULL;
     
    10221631                        struct sockaddr_storage wins_ss;
    10231632                        struct in_addr wins_ip;
    1024                         int flags;
    1025                         bool timed_out;
    10261633
    10271634                        wins_ip = wins_srv_ip_tag(wins_tags[t], src_ip);
     
    10411648                                inet_ntoa(wins_ip), wins_tags[t]));
    10421649
    1043                         sock = open_socket_in(SOCK_DGRAM, 0, 3, &src_ss, true);
    1044                         if (sock == -1) {
    1045                                 continue;
    1046                         }
    1047 
    10481650                        in_addr_to_sockaddr_storage(&wins_ss, wins_ip);
    1049                         ss_list = name_query(sock,
    1050                                                 name,
     1651                        status = name_query(name,
    10511652                                                name_type,
    10521653                                                false,
    10531654                                                true,
    10541655                                                &wins_ss,
     1656                                                talloc_tos(),
     1657                                                &ss_list,
    10551658                                                return_count,
    1056                                                 &flags,
    1057                                                 &timed_out);
     1659                                                NULL);
    10581660
    10591661                        /* exit loop if we got a list of addresses */
    10601662
    1061                         if (ss_list)
     1663                        if (NT_STATUS_IS_OK(status)) {
    10621664                                goto success;
    1063 
    1064                         close(sock);
    1065 
    1066                         if (timed_out) {
    1067                                 /* Timed out wating for WINS server to respond.
     1665                        }
     1666
     1667                        if (NT_STATUS_EQUAL(status,
     1668                                            NT_STATUS_IO_TIMEOUT)) {
     1669                                /* Timed out waiting for WINS server to
     1670                                 * respond.
    10681671                                 * Mark it dead. */
    10691672                                wins_srv_died(wins_ip, src_ip);
    10701673                        } else {
    1071                                 /* The name definately isn't in this
     1674                                /* The name definitely isn't in this
    10721675                                   group of WINS servers.
    10731676                                   goto the next group  */
     
    10861689                status = NT_STATUS_INVALID_PARAMETER;
    10871690
    1088         SAFE_FREE(ss_list);
     1691        TALLOC_FREE(ss_list);
    10891692        wins_srv_tags_free(wins_tags);
    1090         close(sock);
    10911693
    10921694        return status;
     
    11041706         * "lmhosts" means parse the local lmhosts file.
    11051707         */
    1106 
    1107         XFILE *fp;
    1108         char *lmhost_name = NULL;
    1109         int name_type2;
    1110         struct sockaddr_storage return_ss;
     1708        struct sockaddr_storage *ss_list;
    11111709        NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
    11121710        TALLOC_CTX *ctx = NULL;
     
    11191717                name, name_type));
    11201718
    1121         fp = startlmhosts(get_dyn_LMHOSTSFILE());
    1122 
    1123         if ( fp == NULL )
    1124                 return NT_STATUS_NO_SUCH_FILE;
    1125 
    11261719        ctx = talloc_init("resolve_lmhosts");
    11271720        if (!ctx) {
    1128                 endlmhosts(fp);
    11291721                return NT_STATUS_NO_MEMORY;
    11301722        }
    11311723
    1132         while (getlmhostsent(ctx, fp, &lmhost_name, &name_type2, &return_ss)) {
    1133 
    1134                 if (!strequal(name, lmhost_name)) {
    1135                         TALLOC_FREE(lmhost_name);
    1136                         continue;
    1137                 }
    1138 
    1139                 if ((name_type2 != -1) && (name_type != name_type2)) {
    1140                         TALLOC_FREE(lmhost_name);
    1141                         continue;
    1142                 }
    1143 
    1144                 *return_iplist = SMB_REALLOC_ARRAY((*return_iplist),
    1145                                         struct ip_service,
    1146                                         (*return_count)+1);
    1147 
    1148                 if ((*return_iplist) == NULL) {
    1149                         TALLOC_FREE(ctx);
    1150                         endlmhosts(fp);
    1151                         DEBUG(3,("resolve_lmhosts: malloc fail !\n"));
     1724        status = resolve_lmhosts_file_as_sockaddr(get_dyn_LMHOSTSFILE(),
     1725                                                  name, name_type,
     1726                                                  ctx,
     1727                                                  &ss_list,
     1728                                                  return_count);
     1729        if (NT_STATUS_IS_OK(status)) {
     1730                if (convert_ss2service(return_iplist,
     1731                                       ss_list,
     1732                                       *return_count)) {
     1733                        talloc_free(ctx);
     1734                        return NT_STATUS_OK;
     1735                } else {
     1736                        talloc_free(ctx);
    11521737                        return NT_STATUS_NO_MEMORY;
    11531738                }
    1154 
    1155                 (*return_iplist)[*return_count].ss = return_ss;
    1156                 (*return_iplist)[*return_count].port = PORT_NONE;
    1157                 *return_count += 1;
    1158 
    1159                 /* we found something */
    1160                 status = NT_STATUS_OK;
    1161 
    1162                 /* Multiple names only for DC lookup */
    1163                 if (name_type != 0x1c)
    1164                         break;
    1165         }
    1166 
    1167         TALLOC_FREE(ctx);
    1168         endlmhosts(fp);
     1739        }
     1740        talloc_free(ctx);
    11691741        return status;
    11701742}
     
    12571829 Resolve via "ADS" method.
    12581830*********************************************************/
     1831
     1832/* Special name type used to cause a _kerberos DNS lookup. */
     1833#define KDC_NAME_TYPE 0xDCDC
    12591834
    12601835static NTSTATUS resolve_ads(const char *name,
     
    13611936                 * doesn't know anything about the DC's   -- jerry */
    13621937
    1363                 if (!is_zero_addr((struct sockaddr *)&r->ss)) {
     1938                if (!is_zero_addr(&r->ss)) {
    13641939                        (*return_count)++;
    13651940                }
     
    14932068                        }
    14942069                } else if(strequal( tok, "bcast")) {
    1495                         status = name_resolve_bcast(name, name_type,
    1496                                                     return_iplist,
    1497                                                     return_count);
     2070                        struct sockaddr_storage *ss_list;
     2071                        status = name_resolve_bcast(
     2072                                name, name_type, talloc_tos(),
     2073                                &ss_list, return_count);
    14982074                        if (NT_STATUS_IS_OK(status)) {
     2075                                if (!convert_ss2service(return_iplist,
     2076                                                        ss_list,
     2077                                                        *return_count)) {
     2078                                        status = NT_STATUS_NO_MEMORY;
     2079                                }
    14992080                                goto done;
    15002081                        }
     
    15912172                if (prefer_ipv4) {
    15922173                        for (i=0; i<count; i++) {
    1593                                 if (!is_zero_addr((struct sockaddr *)&ss_list[i].ss) &&
     2174                                if (!is_zero_addr(&ss_list[i].ss) &&
    15942175                                                !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss) &&
    15952176                                                (ss_list[i].ss.ss_family == AF_INET)) {
     
    16042185                /* only return valid addresses for TCP connections */
    16052186                for (i=0; i<count; i++) {
    1606                         if (!is_zero_addr((struct sockaddr *)&ss_list[i].ss) &&
     2187                        if (!is_zero_addr(&ss_list[i].ss) &&
    16072188                                        !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss)) {
    16082189                                *return_ss = ss_list[i].ss;
     
    16682249        /* only return valid addresses for TCP connections */
    16692250        for (i=0, num_entries = 0; i<count; i++) {
    1670                 if (!is_zero_addr((struct sockaddr *)&ss_list[i].ss) &&
     2251                if (!is_zero_addr(&ss_list[i].ss) &&
    16712252                                !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss)) {
    16722253                        num_entries++;
     
    16872268
    16882269        for (i=0, num_entries = 0; i<count; i++) {
    1689                 if (!is_zero_addr((struct sockaddr *)&ss_list[i].ss) &&
     2270                if (!is_zero_addr(&ss_list[i].ss) &&
    16902271                                !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss)) {
    16912272                        (*return_ss_arr)[num_entries++] = ss_list[i].ss;
     
    18552436
    18562437        if (strequal(domain, lp_workgroup()) || strequal(domain, lp_realm())) {
    1857                 pserver = talloc_asprintf(NULL, "%s, %s",
     2438                pserver = talloc_asprintf(ctx, "%s, %s",
    18582439                        saf_servername ? saf_servername : "",
    18592440                        lp_passwordserver());
    18602441        } else {
    1861                 pserver = talloc_asprintf(NULL, "%s, *",
     2442                pserver = talloc_asprintf(ctx, "%s, *",
    18622443                        saf_servername ? saf_servername : "");
    18632444        }
Note: See TracChangeset for help on using the changeset viewer.