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/libcli/cldap/cldap.c

    r746 r988  
    6262        bool connected;
    6363
    64         /*
    65          * we allow sync requests only, if the caller
    66          * did not pass an event context to cldap_socket_init()
    67          */
    68         struct {
    69                 bool allow_poll;
    70                 struct tevent_context *ctx;
    71         } event;
    72 
    7364        /* the queue for outgoing dgrams */
    7465        struct tevent_queue *send_queue;
     
    8778        /* what to do with incoming request packets */
    8879        struct {
     80                struct tevent_context *ev;
    8981                void (*handler)(struct cldap_socket *,
    9082                                void *private_data,
     
    9890
    9991        struct {
     92                struct tevent_context *ev;
    10093                struct cldap_socket *cldap;
    10194        } caller;
     
    137130static bool cldap_recvfrom_setup(struct cldap_socket *c)
    138131{
     132        struct tevent_context *ev;
     133
    139134        if (c->recv_subreq) {
    140135                return true;
     
    145140        }
    146141
    147         c->recv_subreq = tdgram_recvfrom_send(c, c->event.ctx, c->sock);
     142        ev = c->incoming.ev;
     143        if (ev == NULL) {
     144                ev = c->searches.list->caller.ev;
     145        }
     146
     147        c->recv_subreq = tdgram_recvfrom_send(c, ev, c->sock);
    148148        if (!c->recv_subreq) {
    149149                return false;
     
    213213        talloc_free(subreq);
    214214        talloc_free(in);
    215         /*TODO: call a dead socket handler */
    216         return;
    217215}
    218216
     
    223221                                    struct cldap_incoming *in)
    224222{
    225         DATA_BLOB blob;
    226223        struct asn1_data *asn1;
    227224        void *p;
     
    233230        }
    234231
    235         blob = data_blob_const(in->buf, in->len);
    236 
    237232        asn1 = asn1_init(in);
    238233        if (!asn1) {
     
    240235        }
    241236
    242         if (!asn1_load(asn1, blob)) {
    243                 goto nomem;
    244         }
     237        asn1_load_nocopy(asn1, in->buf, in->len);
    245238
    246239        in->ldap_msg = talloc(in, struct ldap_message);
     
    259252        if (p == NULL) {
    260253                if (!c->incoming.handler) {
    261                         goto done;
     254                        TALLOC_FREE(in);
     255                        return true;
    262256                }
    263257
     
    267261        }
    268262
    269         search = talloc_get_type(p, struct cldap_search_state);
     263        search = talloc_get_type_abort(p, struct cldap_search_state);
    270264        search->response.in = talloc_move(search, &in);
     265
    271266        search->response.asn1 = asn1;
    272         search->response.asn1->ofs = 0;
     267
     268        asn1_load_nocopy(search->response.asn1,
     269                         search->response.in->buf, search->response.in->len);
    273270
    274271        DLIST_REMOVE(c->searches.list, search);
    275272
    276         cldap_recvfrom_setup(c);
    277 
     273        if (cldap_recvfrom_setup(c)) {
     274                tevent_req_done(search->req);
     275                return true;
     276        }
     277
     278        /*
     279         * This request was ok, just defer the notify of the caller
     280         * and then just fail the next request if needed
     281         */
     282        tevent_req_defer_callback(search->req, search->caller.ev);
    278283        tevent_req_done(search->req);
    279         return true;
    280 
     284
     285        status = NT_STATUS_NO_MEMORY;
     286        /* in is NULL it this point */
     287        goto nterror;
    281288nomem:
    282289        in->recv_errno = ENOMEM;
    283290error:
    284         status = map_nt_error_from_unix(in->recv_errno);
     291        status = map_nt_error_from_unix_common(in->recv_errno);
    285292nterror:
    286293        TALLOC_FREE(in);
     
    288295        if (!c->connected) {
    289296                /* otherwise we just ignore the error */
    290                 goto done;
     297                return false;
    291298        }
    292299        if (!c->searches.list) {
    293                 goto done;
    294         }
    295         cldap_recvfrom_setup(c);
     300                return false;
     301        }
     302        /*
     303         * We might called tevent_req_done() for a successful
     304         * search before, so we better deliver the failure
     305         * after the success, that is why we better also
     306         * use tevent_req_defer_callback() here.
     307         */
     308        tevent_req_defer_callback(c->searches.list->req,
     309                                  c->searches.list->caller.ev);
    296310        tevent_req_nterror(c->searches.list->req, status);
    297         return true;
    298 done:
    299         TALLOC_FREE(in);
    300311        return false;
    301312}
     
    305316*/
    306317NTSTATUS cldap_socket_init(TALLOC_CTX *mem_ctx,
    307                            struct tevent_context *ev,
    308318                           const struct tsocket_address *local_addr,
    309319                           const struct tsocket_address *remote_addr,
     
    341351        }
    342352
    343         if (!ev) {
    344                 ev = tevent_context_init(c);
    345                 if (!ev) {
    346                         goto nomem;
    347                 }
    348                 c->event.allow_poll = true;
    349         }
    350         c->event.ctx = ev;
    351 
    352353        if (!local_addr) {
    353354                /*
     
    362363                                                        &any);
    363364                if (ret != 0) {
    364                         status = map_nt_error_from_unix(errno);
     365                        status = map_nt_error_from_unix_common(errno);
    365366                        goto nterror;
    366367                }
     
    376377                                     c, &c->sock);
    377378        if (ret != 0) {
    378                 status = map_nt_error_from_unix(errno);
     379                status = map_nt_error_from_unix_common(errno);
    379380                goto nterror;
    380381        }
     
    406407*/
    407408NTSTATUS cldap_set_incoming_handler(struct cldap_socket *c,
     409                                    struct tevent_context *ev,
    408410                                    void (*handler)(struct cldap_socket *,
    409411                                                    void *private_data,
     
    415417        }
    416418
    417         /* if sync requests are allowed, we don't allow an incoming handler */
    418         if (c->event.allow_poll) {
    419                 return NT_STATUS_INVALID_PIPE_STATE;
    420         }
    421 
     419        c->incoming.ev = ev;
    422420        c->incoming.handler = handler;
    423421        c->incoming.private_data = private_data;
     
    453451        }
    454452
     453        if (cldap->incoming.ev == NULL) {
     454                return NT_STATUS_INVALID_PIPE_STATE;
     455        }
     456
    455457        if (!io->dest) {
    456458                return NT_STATUS_INVALID_ADDRESS;
     
    505507
    506508        subreq = tdgram_sendto_queue_send(state,
    507                                           cldap->event.ctx,
     509                                          cldap->incoming.ev,
    508510                                          cldap->sock,
    509511                                          cldap->send_queue,
     
    558560*/
    559561struct tevent_req *cldap_search_send(TALLOC_CTX *mem_ctx,
    560                                     struct cldap_socket *cldap,
    561                                     const struct cldap_search *io)
     562                                     struct tevent_context *ev,
     563                                     struct cldap_socket *cldap,
     564                                     const struct cldap_search *io)
    562565{
    563566        struct tevent_req *req, *subreq;
     
    576579        }
    577580        ZERO_STRUCTP(state);
     581        state->caller.ev = ev;
    578582        state->req = req;
    579583        state->caller.cldap = cldap;
     
    651655        end = now;
    652656        for (i = 0; i < state->request.count; i++) {
    653                 end = tevent_timeval_add(&end, 0, state->request.delay);
    654         }
    655 
    656         if (!tevent_req_set_endtime(req, state->caller.cldap->event.ctx, end)) {
    657                 tevent_req_nomem(NULL, req);
     657                end = tevent_timeval_add(&end, state->request.delay / 1000000,
     658                                         state->request.delay % 1000000);
     659        }
     660
     661        if (!tevent_req_set_endtime(req, state->caller.ev, end)) {
     662                tevent_req_oom(req);
    658663                goto post;
    659664        }
    660665
    661666        subreq = tdgram_sendto_queue_send(state,
    662                                           state->caller.cldap->event.ctx,
     667                                          state->caller.ev,
    663668                                          state->caller.cldap->sock,
    664669                                          state->caller.cldap->send_queue,
     
    671676        tevent_req_set_callback(subreq, cldap_search_state_queue_done, req);
    672677
    673         DLIST_ADD_END(cldap->searches.list, state, struct cldap_search_state *);
     678        DLIST_ADD_END(cldap->searches.list, state);
    674679
    675680        return req;
    676681
    677682 post:
    678         return tevent_req_post(req, cldap->event.ctx);
     683        return tevent_req_post(req, state->caller.ev);
    679684}
    680685
     
    693698        if (ret == -1) {
    694699                NTSTATUS status;
    695                 status = map_nt_error_from_unix(sys_errno);
     700                status = map_nt_error_from_unix_common(sys_errno);
    696701                DLIST_REMOVE(state->caller.cldap->searches.list, state);
    697702                ZERO_STRUCT(state->caller.cldap);
     
    704709        /* wait for incoming traffic */
    705710        if (!cldap_recvfrom_setup(state->caller.cldap)) {
    706                 tevent_req_nomem(NULL, req);
     711                tevent_req_oom(req);
    707712                return;
    708713        }
     
    713718        }
    714719
    715         next = tevent_timeval_current_ofs(0, state->request.delay);
     720        next = tevent_timeval_current_ofs(state->request.delay / 1000000,
     721                                          state->request.delay % 1000000);
    716722        subreq = tevent_wakeup_send(state,
    717                                     state->caller.cldap->event.ctx,
     723                                    state->caller.ev,
    718724                                    next);
    719725        if (tevent_req_nomem(subreq, req)) {
     
    739745
    740746        subreq = tdgram_sendto_queue_send(state,
    741                                           state->caller.cldap->event.ctx,
     747                                          state->caller.ev,
    742748                                          state->caller.cldap->sock,
    743749                                          state->caller.cldap->send_queue,
     
    828834                      struct cldap_search *io)
    829835{
     836        TALLOC_CTX *frame;
    830837        struct tevent_req *req;
     838        struct tevent_context *ev;
    831839        NTSTATUS status;
    832 
    833         if (!cldap->event.allow_poll) {
    834                 return NT_STATUS_INVALID_PIPE_STATE;
    835         }
    836840
    837841        if (cldap->searches.list) {
     
    839843        }
    840844
    841         req = cldap_search_send(mem_ctx, cldap, io);
    842         NT_STATUS_HAVE_NO_MEMORY(req);
    843 
    844         if (!tevent_req_poll(req, cldap->event.ctx)) {
    845                 talloc_free(req);
    846                 return NT_STATUS_INTERNAL_ERROR;
     845        if (cldap->incoming.handler) {
     846                return NT_STATUS_INVALID_PIPE_STATE;
     847        }
     848
     849        frame = talloc_stackframe();
     850
     851        ev = samba_tevent_context_init(frame);
     852        if (ev == NULL) {
     853                TALLOC_FREE(frame);
     854                return NT_STATUS_NO_MEMORY;
     855        }
     856
     857        req = cldap_search_send(mem_ctx, ev, cldap, io);
     858        if (req == NULL) {
     859                TALLOC_FREE(frame);
     860                return NT_STATUS_NO_MEMORY;
     861        }
     862
     863        if (!tevent_req_poll(req, ev)) {
     864                status = map_nt_error_from_unix_common(errno);
     865                TALLOC_FREE(frame);
     866                return status;
    847867        }
    848868
    849869        status = cldap_search_recv(req, mem_ctx, io);
    850         talloc_free(req);
    851 
    852         return status;
     870        if (!NT_STATUS_IS_OK(status)) {
     871                TALLOC_FREE(frame);
     872                return status;
     873        }
     874
     875        TALLOC_FREE(frame);
     876        return NT_STATUS_OK;
    853877}
    854878
     
    857881};
    858882
     883char *cldap_netlogon_create_filter(TALLOC_CTX *mem_ctx,
     884                                   const struct cldap_netlogon *io)
     885{
     886        char *filter;
     887
     888        filter = talloc_asprintf(mem_ctx, "(&(NtVer=%s)",
     889                                 ldap_encode_ndr_uint32(mem_ctx, io->in.version));
     890        if (filter == NULL)
     891                return NULL;
     892
     893        if (io->in.user) {
     894                filter = talloc_asprintf_append_buffer(filter, "(User=%s)", io->in.user);
     895                if (filter == NULL) {
     896                        return NULL;
     897                }
     898        }
     899        if (io->in.host) {
     900                filter = talloc_asprintf_append_buffer(filter, "(Host=%s)", io->in.host);
     901                if (filter == NULL) {
     902                        return NULL;
     903                }
     904        }
     905        if (io->in.realm) {
     906                filter = talloc_asprintf_append_buffer(filter, "(DnsDomain=%s)", io->in.realm);
     907                if (filter == NULL) {
     908                        return NULL;
     909                }
     910        }
     911        if (io->in.acct_control != -1) {
     912                filter = talloc_asprintf_append_buffer(filter, "(AAC=%s)",
     913                                                ldap_encode_ndr_uint32(mem_ctx, io->in.acct_control));
     914                if (filter == NULL) {
     915                        return NULL;
     916                }
     917        }
     918        if (io->in.domain_sid) {
     919                struct dom_sid *sid = dom_sid_parse_talloc(mem_ctx, io->in.domain_sid);
     920
     921                filter = talloc_asprintf_append_buffer(filter, "(domainSid=%s)",
     922                                                ldap_encode_ndr_dom_sid(mem_ctx, sid));
     923                if (filter == NULL) {
     924                        return NULL;
     925                }
     926        }
     927        if (io->in.domain_guid) {
     928                struct GUID guid;
     929                GUID_from_string(io->in.domain_guid, &guid);
     930
     931                filter = talloc_asprintf_append_buffer(filter, "(DomainGuid=%s)",
     932                                                ldap_encode_ndr_GUID(mem_ctx, &guid));
     933                if (filter == NULL) {
     934                        return NULL;
     935                }
     936        }
     937        filter = talloc_asprintf_append_buffer(filter, ")");
     938
     939        return filter;
     940}
     941
    859942static void cldap_netlogon_state_done(struct tevent_req *subreq);
    860943/*
     
    862945*/
    863946struct tevent_req *cldap_netlogon_send(TALLOC_CTX *mem_ctx,
    864                                       struct cldap_socket *cldap,
    865                                       const struct cldap_netlogon *io)
     947                                       struct tevent_context *ev,
     948                                       struct cldap_socket *cldap,
     949                                       const struct cldap_netlogon *io)
    866950{
    867951        struct tevent_req *req, *subreq;
     
    876960        }
    877961
    878         filter = talloc_asprintf(state, "(&(NtVer=%s)",
    879                                  ldap_encode_ndr_uint32(state, io->in.version));
    880         if (tevent_req_nomem(filter, req)) {
    881                 goto post;
    882         }
    883         if (io->in.user) {
    884                 filter = talloc_asprintf_append_buffer(filter, "(User=%s)", io->in.user);
    885                 if (tevent_req_nomem(filter, req)) {
    886                         goto post;
    887                 }
    888         }
    889         if (io->in.host) {
    890                 filter = talloc_asprintf_append_buffer(filter, "(Host=%s)", io->in.host);
    891                 if (tevent_req_nomem(filter, req)) {
    892                         goto post;
    893                 }
    894         }
    895         if (io->in.realm) {
    896                 filter = talloc_asprintf_append_buffer(filter, "(DnsDomain=%s)", io->in.realm);
    897                 if (tevent_req_nomem(filter, req)) {
    898                         goto post;
    899                 }
    900         }
    901         if (io->in.acct_control != -1) {
    902                 filter = talloc_asprintf_append_buffer(filter, "(AAC=%s)",
    903                                                 ldap_encode_ndr_uint32(state, io->in.acct_control));
    904                 if (tevent_req_nomem(filter, req)) {
    905                         goto post;
    906                 }
    907         }
    908         if (io->in.domain_sid) {
    909                 struct dom_sid *sid = dom_sid_parse_talloc(state, io->in.domain_sid);
    910                 if (tevent_req_nomem(sid, req)) {
    911                         goto post;
    912                 }
    913                 filter = talloc_asprintf_append_buffer(filter, "(domainSid=%s)",
    914                                                 ldap_encode_ndr_dom_sid(state, sid));
    915                 if (tevent_req_nomem(filter, req)) {
    916                         goto post;
    917                 }
    918         }
    919         if (io->in.domain_guid) {
    920                 struct GUID guid;
    921                 NTSTATUS status;
    922                 status = GUID_from_string(io->in.domain_guid, &guid);
    923                 if (tevent_req_nterror(req, status)) {
    924                         goto post;
    925                 }
    926                 filter = talloc_asprintf_append_buffer(filter, "(DomainGuid=%s)",
    927                                                 ldap_encode_ndr_GUID(state, &guid));
    928                 if (tevent_req_nomem(filter, req)) {
    929                         goto post;
    930                 }
    931         }
    932         filter = talloc_asprintf_append_buffer(filter, ")");
     962        filter = cldap_netlogon_create_filter(state, io);
    933963        if (tevent_req_nomem(filter, req)) {
    934964                goto post;
     
    951981        state->search.in.retries        = 2;
    952982
    953         subreq = cldap_search_send(state, cldap, &state->search);
     983        subreq = cldap_search_send(state, ev, cldap, &state->search);
    954984        if (tevent_req_nomem(subreq, req)) {
    955985                goto post;
     
    959989        return req;
    960990post:
    961         return tevent_req_post(req, cldap->event.ctx);
     991        return tevent_req_post(req, ev);
    962992}
    963993
     
    9891019        struct cldap_netlogon_state *state = tevent_req_data(req,
    9901020                                             struct cldap_netlogon_state);
    991         NTSTATUS status;
     1021        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
    9921022        DATA_BLOB *data;
    9931023
     
    10331063                        struct cldap_netlogon *io)
    10341064{
     1065        TALLOC_CTX *frame;
    10351066        struct tevent_req *req;
     1067        struct tevent_context *ev;
    10361068        NTSTATUS status;
    1037 
    1038         if (!cldap->event.allow_poll) {
    1039                 return NT_STATUS_INVALID_PIPE_STATE;
    1040         }
    10411069
    10421070        if (cldap->searches.list) {
     
    10441072        }
    10451073
    1046         req = cldap_netlogon_send(mem_ctx, cldap, io);
    1047         NT_STATUS_HAVE_NO_MEMORY(req);
    1048 
    1049         if (!tevent_req_poll(req, cldap->event.ctx)) {
    1050                 talloc_free(req);
    1051                 return NT_STATUS_INTERNAL_ERROR;
     1074        if (cldap->incoming.handler) {
     1075                return NT_STATUS_INVALID_PIPE_STATE;
     1076        }
     1077
     1078        frame = talloc_stackframe();
     1079
     1080        ev = samba_tevent_context_init(frame);
     1081        if (ev == NULL) {
     1082                TALLOC_FREE(frame);
     1083                return NT_STATUS_NO_MEMORY;
     1084        }
     1085
     1086        req = cldap_netlogon_send(mem_ctx, ev, cldap, io);
     1087        if (req == NULL) {
     1088                TALLOC_FREE(frame);
     1089                return NT_STATUS_NO_MEMORY;
     1090        }
     1091
     1092        if (!tevent_req_poll(req, ev)) {
     1093                status = map_nt_error_from_unix_common(errno);
     1094                TALLOC_FREE(frame);
     1095                return status;
    10521096        }
    10531097
    10541098        status = cldap_netlogon_recv(req, mem_ctx, io);
    1055         talloc_free(req);
    1056 
    1057         return status;
     1099        if (!NT_STATUS_IS_OK(status)) {
     1100                TALLOC_FREE(frame);
     1101                return status;
     1102        }
     1103
     1104        TALLOC_FREE(frame);
     1105        return NT_STATUS_OK;
    10581106}
    10591107
Note: See TracChangeset for help on using the changeset viewer.