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

Location:
vendor/current/source4/libcli/ldap
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source4/libcli/ldap/ldap_bind.c

    r740 r988  
    2828#include "lib/tls/tls.h"
    2929#include "auth/gensec/gensec.h"
     30#include "auth/gensec/gensec_internal.h" /* TODO: remove this */
     31#include "source4/auth/gensec/gensec_tstream.h"
    3032#include "auth/credentials/credentials.h"
    3133#include "lib/stream/packet.h"
    3234#include "param/param.h"
     35#include "param/loadparm.h"
    3336
    3437struct ldap_simple_creds {
     
    214217        struct ldap_SearchResEntry *search;
    215218        int count, i;
    216 
     219        bool first = true;
     220        int wrap_flags = 0;
    217221        const char **sasl_names;
    218222        uint32_t old_gensec_features;
     
    221225                NULL
    222226        };
    223 
    224         gensec_init(lp_ctx);
     227        unsigned int logon_retries = 0;
     228        size_t queue_length;
     229
     230        if (conn->sockets.active == NULL) {
     231                status = NT_STATUS_CONNECTION_DISCONNECTED;
     232                goto failed;
     233        }
     234
     235        queue_length = tevent_queue_length(conn->sockets.send_queue);
     236        if (queue_length != 0) {
     237                status = NT_STATUS_INVALID_PARAMETER_MIX;
     238                DEBUG(1, ("SASL bind triggered with non empty send_queue[%zu]: %s\n",
     239                          queue_length, nt_errstr(status)));
     240                goto failed;
     241        }
     242
     243        if (conn->pending != NULL) {
     244                status = NT_STATUS_INVALID_PARAMETER_MIX;
     245                DEBUG(1, ("SASL bind triggered with pending requests: %s\n",
     246                          nt_errstr(status)));
     247                goto failed;
     248        }
     249
     250        status = ildap_search(conn, "", LDAP_SEARCH_SCOPE_BASE, "", supported_sasl_mech_attrs,
     251                              false, NULL, NULL, &sasl_mechs_msgs);
     252        if (!NT_STATUS_IS_OK(status)) {
     253                DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: %s\n",
     254                          nt_errstr(status)));
     255                goto failed;
     256        }
     257
     258        count = ildap_count_entries(conn, sasl_mechs_msgs);
     259        if (count != 1) {
     260                DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: wrong number of replies: %d\n",
     261                          count));
     262                goto failed;
     263        }
     264
     265        tmp_ctx = talloc_new(conn);
     266        if (tmp_ctx == NULL) goto failed;
     267
     268        search = &sasl_mechs_msgs[0]->r.SearchResultEntry;
     269        if (search->num_attributes != 1) {
     270                DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: wrong number of attributes: %d != 1\n",
     271                          search->num_attributes));
     272                goto failed;
     273        }
     274
     275        sasl_names = talloc_array(tmp_ctx, const char *, search->attributes[0].num_values + 1);
     276        if (!sasl_names) {
     277                DEBUG(1, ("talloc_arry(char *, %d) failed\n",
     278                          count));
     279                goto failed;
     280        }
     281
     282        for (i=0; i<search->attributes[0].num_values; i++) {
     283                sasl_names[i] = (const char *)search->attributes[0].values[i].data;
     284        }
     285        sasl_names[i] = NULL;
     286
     287        gensec_init();
     288
     289        if (conn->sockets.active == conn->sockets.tls) {
     290                /*
     291                 * require Kerberos SIGN/SEAL only if we don't use SSL
     292                 * Windows seem not to like double encryption
     293                 */
     294                wrap_flags = 0;
     295        } else if (cli_credentials_is_anonymous(creds)) {
     296                /*
     297                 * anonymous isn't protected
     298                 */
     299                wrap_flags = 0;
     300        } else {
     301                wrap_flags = lpcfg_client_ldap_sasl_wrapping(lp_ctx);
     302        }
     303
     304try_logon_again:
     305        /*
     306          we loop back here on a logon failure, and re-create the
     307          gensec session. The logon_retries counter ensures we don't
     308          loop forever.
     309         */
     310        data_blob_free(&input);
     311        TALLOC_FREE(conn->gensec);
    225312
    226313        status = gensec_client_start(conn, &conn->gensec,
    227                                      conn->event.event_ctx,
    228314                                     lpcfg_gensec_settings(conn, lp_ctx));
    229315        if (!NT_STATUS_IS_OK(status)) {
     
    232318        }
    233319
    234         /* require Kerberos SIGN/SEAL only if we don't use SSL
    235          * Windows seem not to like double encryption */
    236320        old_gensec_features = cli_credentials_get_gensec_features(creds);
    237         if (tls_enabled(conn->sock)) {
     321        if (wrap_flags == 0) {
    238322                cli_credentials_set_gensec_features(creds, old_gensec_features & ~(GENSEC_FEATURE_SIGN|GENSEC_FEATURE_SEAL));
    239323        }
     
    250334         * context, so we don't tatoo it ) */
    251335        cli_credentials_set_gensec_features(creds, old_gensec_features);
     336
     337        if (wrap_flags & ADS_AUTH_SASL_SEAL) {
     338                gensec_want_feature(conn->gensec, GENSEC_FEATURE_SIGN);
     339                gensec_want_feature(conn->gensec, GENSEC_FEATURE_SEAL);
     340        }
     341        if (wrap_flags & ADS_AUTH_SASL_SIGN) {
     342                gensec_want_feature(conn->gensec, GENSEC_FEATURE_SIGN);
     343        }
     344
     345        /*
     346         * This is an indication for the NTLMSSP backend to
     347         * also encrypt when only GENSEC_FEATURE_SIGN is requested
     348         * in gensec_[un]wrap().
     349         */
     350        gensec_want_feature(conn->gensec, GENSEC_FEATURE_LDAP_STYLE);
    252351
    253352        if (conn->host) {
     
    267366        }
    268367
    269         status = ildap_search(conn, "", LDAP_SEARCH_SCOPE_BASE, "", supported_sasl_mech_attrs,
    270                               false, NULL, NULL, &sasl_mechs_msgs);
    271         if (!NT_STATUS_IS_OK(status)) {
    272                 DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: %s\n",
    273                           nt_errstr(status)));
    274                 goto failed;
    275         }
    276        
    277         count = ildap_count_entries(conn, sasl_mechs_msgs);
    278         if (count != 1) {
    279                 DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: wrong number of replies: %d\n",
    280                           count));
    281                 goto failed;
    282         }
    283 
    284         tmp_ctx = talloc_new(conn);
    285         if (tmp_ctx == NULL) goto failed;
    286 
    287         search = &sasl_mechs_msgs[0]->r.SearchResultEntry;
    288         if (search->num_attributes != 1) {
    289                 DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: wrong number of attributes: %d != 1\n",
    290                           search->num_attributes));
    291                 goto failed;
    292         }
    293 
    294         sasl_names = talloc_array(tmp_ctx, const char *, search->attributes[0].num_values + 1);
    295         if (!sasl_names) {
    296                 DEBUG(1, ("talloc_arry(char *, %d) failed\n",
    297                           count));
    298                 goto failed;
    299         }
    300                
    301         for (i=0; i<search->attributes[0].num_values; i++) {
    302                 sasl_names[i] = (const char *)search->attributes[0].values[i].data;
    303         }
    304         sasl_names[i] = NULL;
    305        
    306368        status = gensec_start_mech_by_sasl_list(conn->gensec, sasl_names);
    307369        if (!NT_STATUS_IS_OK(status)) {
     
    318380                int result = LDAP_OTHER;
    319381       
    320                 status = gensec_update(conn->gensec, tmp_ctx,
     382                status = gensec_update_ev(conn->gensec, tmp_ctx,
     383                                       conn->event.event_ctx,
    321384                                       input,
    322385                                       &output);
     
    328391                 *
    329392                 * Likewise, you must not feed GENSEC too much (after the OK),
    330                  * it doesn't like that either
     393                 * it doesn't like that either.
     394                 *
     395                 * For SASL/EXTERNAL, there is no data to send, but we still
     396                 * must send the actual Bind request the first time around.
     397                 * Otherwise, a result of NT_STATUS_OK with 0 output means the
     398                 * end of a multi-step authentication, and no message must be
     399                 * sent.
    331400                 */
    332401
     
    338407                }
    339408                if (NT_STATUS_IS_OK(status) && output.length == 0) {
    340                         break;
    341                 }
     409                        if (!first)
     410                                break;
     411                }
     412                first = false;
    342413
    343414                /* Perhaps we should make gensec_start_mech_by_sasl_list() return the name we got? */
     
    367438                result = response->r.BindResponse.response.resultcode;
    368439
     440                if (result == LDAP_STRONG_AUTH_REQUIRED) {
     441                        if (wrap_flags == 0) {
     442                                wrap_flags = ADS_AUTH_SASL_SIGN;
     443                                goto try_logon_again;
     444                        }
     445                }
     446
     447                if (result == LDAP_INVALID_CREDENTIALS) {
     448                        /*
     449                          try a second time on invalid credentials, to
     450                          give the user a chance to re-enter the
     451                          password and to handle the case where our
     452                          kerberos ticket is invalid as the server
     453                          password has changed
     454                        */
     455                        const char *principal;
     456
     457                        principal = gensec_get_target_principal(conn->gensec);
     458                        if (principal == NULL) {
     459                                const char *hostname = gensec_get_target_hostname(conn->gensec);
     460                                const char *service  = gensec_get_target_service(conn->gensec);
     461                                if (hostname != NULL && service != NULL) {
     462                                        principal = talloc_asprintf(tmp_ctx, "%s/%s", service, hostname);
     463                                }
     464                        }
     465
     466                        if (cli_credentials_failed_kerberos_login(creds, principal, &logon_retries) ||
     467                            cli_credentials_wrong_password(creds)) {
     468                                /*
     469                                  destroy our gensec session and loop
     470                                  back up to the top to retry,
     471                                  offering the user a chance to enter
     472                                  new credentials, or get a new ticket
     473                                  if using kerberos
     474                                 */
     475                                goto try_logon_again;
     476                        }
     477                }
     478
    369479                if (result != LDAP_SUCCESS && result != LDAP_SASL_BIND_IN_PROGRESS) {
    370480                        status = ldap_check_response(conn,
     
    384494        }
    385495
    386         talloc_free(tmp_ctx);
    387 
    388         if (NT_STATUS_IS_OK(status)) {
    389                 struct socket_context *sasl_socket;
    390                 status = gensec_socket_init(conn->gensec,
    391                                             conn,
    392                                             conn->sock,
    393                                             conn->event.event_ctx,
    394                                             ldap_read_io_handler,
    395                                             conn,
    396                                             &sasl_socket);
    397                 if (!NT_STATUS_IS_OK(status)) goto failed;
    398 
    399                 conn->sock = sasl_socket;
    400                 packet_set_socket(conn->packet, conn->sock);
    401 
    402                 conn->bind.type = LDAP_BIND_SASL;
    403                 conn->bind.creds = creds;
    404         }
    405 
    406         return status;
     496        TALLOC_FREE(tmp_ctx);
     497
     498        if (!NT_STATUS_IS_OK(status)) {
     499                goto failed;
     500        }
     501
     502        conn->bind.type = LDAP_BIND_SASL;
     503        conn->bind.creds = creds;
     504
     505        if (wrap_flags & ADS_AUTH_SASL_SEAL) {
     506                if (!gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN)) {
     507                        return NT_STATUS_INVALID_NETWORK_RESPONSE;
     508                }
     509
     510                if (!gensec_have_feature(conn->gensec, GENSEC_FEATURE_SEAL)) {
     511                        return NT_STATUS_INVALID_NETWORK_RESPONSE;
     512                }
     513        } else if (wrap_flags & ADS_AUTH_SASL_SIGN) {
     514                if (!gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN)) {
     515                        return NT_STATUS_INVALID_NETWORK_RESPONSE;
     516                }
     517        }
     518
     519        if (!gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN) &&
     520            !gensec_have_feature(conn->gensec, GENSEC_FEATURE_SEAL)) {
     521                return NT_STATUS_OK;
     522        }
     523
     524        status = gensec_create_tstream(conn->sockets.raw,
     525                                       conn->gensec,
     526                                       conn->sockets.raw,
     527                                       &conn->sockets.sasl);
     528        if (!NT_STATUS_IS_OK(status)) {
     529                goto failed;
     530        }
     531
     532        conn->sockets.active = conn->sockets.sasl;
     533
     534        return NT_STATUS_OK;
    407535
    408536failed:
  • vendor/current/source4/libcli/ldap/ldap_client.c

    r740 r988  
    2626#include <tevent.h>
    2727#include "lib/socket/socket.h"
     28#include "lib/tsocket/tsocket.h"
     29#include "libcli/util/tstream.h"
    2830#include "../lib/util/asn1.h"
    2931#include "../lib/util/dlinklist.h"
     
    3234#include "libcli/ldap/ldap_client.h"
    3335#include "libcli/composite/composite.h"
    34 #include "lib/stream/packet.h"
    3536#include "lib/tls/tls.h"
    3637#include "auth/gensec/gensec.h"
     
    3940#include "libcli/resolve/resolve.h"
    4041
     42static void ldap_connection_dead(struct ldap_connection *conn, NTSTATUS status);
     43
     44static int ldap_connection_destructor(struct ldap_connection *conn)
     45{
     46        /*
     47         * NT_STATUS_OK means that callbacks of pending requests are not
     48         * triggered
     49         */
     50        ldap_connection_dead(conn, NT_STATUS_OK);
     51        return 0;
     52}
     53
    4154/**
    4255  create a new ldap_connection stucture. The event context is optional
    4356*/
     57
    4458_PUBLIC_ struct ldap_connection *ldap4_new_connection(TALLOC_CTX *mem_ctx,
    4559                                             struct loadparm_context *lp_ctx,
     
    6074        conn->event.event_ctx = ev;
    6175
     76        conn->sockets.send_queue = tevent_queue_create(conn,
     77                                        "ldap_connection send_queue");
     78        if (conn->sockets.send_queue == NULL) {
     79                TALLOC_FREE(conn);
     80                return NULL;
     81        }
     82
    6283        conn->lp_ctx = lp_ctx;
    6384
     
    6788        /* explicitly avoid reconnections by default */
    6889        conn->reconnect.max_retries = 0;
    69        
     90
     91        talloc_set_destructor(conn, ldap_connection_destructor);
    7092        return conn;
    7193}
     
    7496  the connection is dead
    7597*/
    76 static void ldap_connection_dead(struct ldap_connection *conn)
     98static void ldap_connection_dead(struct ldap_connection *conn, NTSTATUS status)
    7799{
    78100        struct ldap_request *req;
    79101
    80         talloc_free(conn->sock);  /* this will also free event.fde */
    81         talloc_free(conn->packet);
    82         conn->sock = NULL;
    83         conn->event.fde = NULL;
    84         conn->packet = NULL;
     102        tevent_queue_stop(conn->sockets.send_queue);
     103        TALLOC_FREE(conn->sockets.recv_subreq);
     104        conn->sockets.active = NULL;
     105        TALLOC_FREE(conn->sockets.sasl);
     106        TALLOC_FREE(conn->sockets.tls);
     107        TALLOC_FREE(conn->sockets.raw);
    85108
    86109        /* return an error for any pending request ... */
     
    88111                req = conn->pending;
    89112                DLIST_REMOVE(req->conn->pending, req);
     113                req->conn = NULL;
    90114                req->state = LDAP_REQUEST_DONE;
    91                 req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR;
     115                if (NT_STATUS_IS_OK(status)) {
     116                        continue;
     117                }
     118                req->status = status;
    92119                if (req->async.fn) {
    93120                        req->async.fn(req);
     
    101128  handle packet errors
    102129*/
    103 static void ldap_error_handler(void *private_data, NTSTATUS status)
    104 {
    105         struct ldap_connection *conn = talloc_get_type(private_data,
    106                                                        struct ldap_connection);
    107         ldap_connection_dead(conn);
     130static void ldap_error_handler(struct ldap_connection *conn, NTSTATUS status)
     131{
     132        ldap_connection_dead(conn, status);
    108133
    109134        /* but try to reconnect so that the ldb client can go on */
     
    131156                DEBUG(0,("ldap: no matching message id for %u\n",
    132157                         msg->messageid));
    133                 talloc_free(msg);
     158                TALLOC_FREE(msg);
    134159                return;
    135160        }
     
    139164                if (!msg->controls_decoded[i] &&
    140165                    msg->controls[i]->critical) {
     166                        TALLOC_FREE(msg);
    141167                        req->status = NT_STATUS_LDAP(LDAP_UNAVAILABLE_CRITICAL_EXTENSION);
    142168                        req->state = LDAP_REQUEST_DONE;
     
    150176
    151177        /* add to the list of replies received */
    152         talloc_steal(req, msg);
    153178        req->replies = talloc_realloc(req, req->replies,
    154179                                      struct ldap_message *, req->num_replies+1);
    155180        if (req->replies == NULL) {
     181                TALLOC_FREE(msg);
    156182                req->status = NT_STATUS_NO_MEMORY;
    157183                req->state = LDAP_REQUEST_DONE;
     
    179205}
    180206
     207static void ldap_connection_recv_done(struct tevent_req *subreq);
     208
     209static void ldap_connection_recv_next(struct ldap_connection *conn)
     210{
     211        struct tevent_req *subreq = NULL;
     212
     213        if (conn->sockets.recv_subreq != NULL) {
     214                return;
     215        }
     216
     217        if (conn->sockets.active == NULL) {
     218                return;
     219        }
     220
     221        if (conn->pending == NULL) {
     222                return;
     223        }
     224
     225        /*
     226         * The minimum size of a LDAP pdu is 7 bytes
     227         *
     228         * dumpasn1 -hh ldap-unbind-min.dat
     229         *
     230         *     <30 05 02 01 09 42 00>
     231         *    0    5: SEQUENCE {
     232         *     <02 01 09>
     233         *    2    1:   INTEGER 9
     234         *     <42 00>
     235         *    5    0:   [APPLICATION 2]
     236         *          :     Error: Object has zero length.
     237         *          :   }
     238         *
     239         * dumpasn1 -hh ldap-unbind-windows.dat
     240         *
     241         *     <30 84 00 00 00 05 02 01 09 42 00>
     242         *    0    5: SEQUENCE {
     243         *     <02 01 09>
     244         *    6    1:   INTEGER 9
     245         *     <42 00>
     246         *    9    0:   [APPLICATION 2]
     247         *          :     Error: Object has zero length.
     248         *          :   }
     249         *
     250         * This means using an initial read size
     251         * of 7 is ok.
     252         */
     253        subreq = tstream_read_pdu_blob_send(conn,
     254                                            conn->event.event_ctx,
     255                                            conn->sockets.active,
     256                                            7, /* initial_read_size */
     257                                            ldap_full_packet,
     258                                            conn);
     259        if (subreq == NULL) {
     260                ldap_error_handler(conn, NT_STATUS_NO_MEMORY);
     261                return;
     262        }
     263        tevent_req_set_callback(subreq, ldap_connection_recv_done, conn);
     264        conn->sockets.recv_subreq = subreq;
     265        return;
     266}
    181267
    182268/*
    183269  decode/process LDAP data
    184270*/
    185 static NTSTATUS ldap_recv_handler(void *private_data, DATA_BLOB blob)
     271static void ldap_connection_recv_done(struct tevent_req *subreq)
    186272{
    187273        NTSTATUS status;
    188         struct ldap_connection *conn = talloc_get_type(private_data,
    189                                                        struct ldap_connection);
    190         struct ldap_message *msg = talloc(conn, struct ldap_message);
    191         struct asn1_data *asn1 = asn1_init(conn);
    192 
    193         if (asn1 == NULL || msg == NULL) {
    194                 return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);
    195         }
    196 
    197         if (!asn1_load(asn1, blob)) {
    198                 talloc_free(msg);
    199                 talloc_free(asn1);
    200                 return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);
    201         }
    202        
     274        struct ldap_connection *conn =
     275                tevent_req_callback_data(subreq,
     276                struct ldap_connection);
     277        struct ldap_message *msg;
     278        struct asn1_data *asn1;
     279        DATA_BLOB blob;
     280
     281        msg = talloc_zero(conn, struct ldap_message);
     282        if (msg == NULL) {
     283                ldap_error_handler(conn, NT_STATUS_NO_MEMORY);
     284                return;
     285        }
     286
     287        asn1 = asn1_init(conn);
     288        if (asn1 == NULL) {
     289                TALLOC_FREE(msg);
     290                ldap_error_handler(conn, NT_STATUS_NO_MEMORY);
     291                return;
     292        }
     293
     294        conn->sockets.recv_subreq = NULL;
     295
     296        status = tstream_read_pdu_blob_recv(subreq,
     297                                            asn1,
     298                                            &blob);
     299        TALLOC_FREE(subreq);
     300        if (!NT_STATUS_IS_OK(status)) {
     301                TALLOC_FREE(msg);
     302                asn1_free(asn1);
     303                ldap_error_handler(conn, status);
     304                return;
     305        }
     306
     307        asn1_load_nocopy(asn1, blob.data, blob.length);
     308
    203309        status = ldap_decode(asn1, samba_ldap_control_handlers(), msg);
     310        asn1_free(asn1);
    204311        if (!NT_STATUS_IS_OK(status)) {
    205                 asn1_free(asn1);
    206                 return status;
     312                TALLOC_FREE(msg);
     313                ldap_error_handler(conn, status);
     314                return;
    207315        }
    208316
    209317        ldap_match_message(conn, msg);
    210 
    211         data_blob_free(&blob);
    212         asn1_free(asn1);
    213         return NT_STATUS_OK;
    214 }
    215 
    216 /* Handle read events, from the GENSEC socket callback, or real events */
    217 void ldap_read_io_handler(void *private_data, uint16_t flags)
    218 {
    219         struct ldap_connection *conn = talloc_get_type(private_data,
    220                                                        struct ldap_connection);
    221         packet_recv(conn->packet);
    222 }
    223 
    224 /*
    225   handle ldap socket events
    226 */
    227 static void ldap_io_handler(struct tevent_context *ev, struct tevent_fd *fde,
    228                             uint16_t flags, void *private_data)
    229 {
    230         struct ldap_connection *conn = talloc_get_type(private_data,
    231                                                        struct ldap_connection);
    232         if (flags & TEVENT_FD_WRITE) {
    233                 packet_queue_run(conn->packet);
    234                 if (!tls_enabled(conn->sock)) return;
    235         }
    236         if (flags & TEVENT_FD_READ) {
    237                 ldap_read_io_handler(private_data, flags);
    238         }
     318        ldap_connection_recv_next(conn);
     319
     320        return;
    239321}
    240322
     
    285367        struct composite_context *ctx;
    286368        struct ldap_connection *conn;
     369        struct socket_context *sock;
     370        struct tstream_context *raw;
     371        struct tstream_tls_params *tls_params;
     372        struct tstream_context *tls;
    287373};
    288374
     
    328414                char path[1025];
    329415       
    330                 NTSTATUS status = socket_create("unix", SOCKET_TYPE_STREAM, &conn->sock, 0);
     416                NTSTATUS status = socket_create("unix", SOCKET_TYPE_STREAM, &state->sock, 0);
    331417                if (!NT_STATUS_IS_OK(status)) {
    332418                        return NULL;
    333419                }
    334                 talloc_steal(conn, conn->sock);
     420                talloc_steal(state, state->sock);
    335421                SMB_ASSERT(sizeof(protocol)>10);
    336422                SMB_ASSERT(sizeof(path)>1024);
     
    355441
    356442                rfc1738_unescape(path);
    357        
    358                 unix_addr = socket_address_from_strings(conn, conn->sock->backend_name,
     443
     444                unix_addr = socket_address_from_strings(state, state->sock->backend_name,
    359445                                                        path, 0);
    360                 if (!unix_addr) {
    361                         return NULL;
    362                 }
    363 
    364                 ctx = socket_connect_send(conn->sock, NULL, unix_addr,
    365                                           0, conn->event.event_ctx);
     446                if (composite_nomem(unix_addr, result)) {
     447                        return result;
     448                }
     449
     450
     451                ctx = socket_connect_send(state->sock, NULL, unix_addr,
     452                                          0, result->event_ctx);
    366453                ctx->async.fn = ldap_connect_recv_unix_conn;
    367454                ctx->async.private_data = state;
     
    370457                NTSTATUS status = ldap_parse_basic_url(conn, url, &conn->host,
    371458                                                          &conn->port, &conn->ldaps);
    372                 if (!NT_STATUS_IS_OK(state->ctx->status)) {
    373                         composite_error(state->ctx, status);
     459                if (!NT_STATUS_IS_OK(status)) {
     460                        composite_error(result, status);
    374461                        return result;
    375462                }
    376                
     463
     464                if (conn->ldaps) {
     465                        char *ca_file = lpcfg_tls_cafile(state, conn->lp_ctx);
     466                        char *crl_file = lpcfg_tls_crlfile(state, conn->lp_ctx);
     467                        const char *tls_priority = lpcfg_tls_priority(conn->lp_ctx);
     468                        enum tls_verify_peer_state verify_peer =
     469                                lpcfg_tls_verify_peer(conn->lp_ctx);
     470
     471                        status = tstream_tls_params_client(state,
     472                                                           ca_file,
     473                                                           crl_file,
     474                                                           tls_priority,
     475                                                           verify_peer,
     476                                                           conn->host,
     477                                                           &state->tls_params);
     478                        if (!NT_STATUS_IS_OK(status)) {
     479                                composite_error(result, status);
     480                                return result;
     481                        }
     482                }
     483
    377484                ctx = socket_connect_multi_send(state, conn->host, 1, &conn->port,
    378                                                 lpcfg_resolve_context(conn->lp_ctx), conn->event.event_ctx);
    379                 if (ctx == NULL) goto failed;
     485                                                lpcfg_resolve_context(conn->lp_ctx),
     486                                                result->event_ctx);
     487                if (composite_nomem(ctx, result)) {
     488                        return result;
     489                }
    380490
    381491                ctx->async.fn = ldap_connect_recv_tcp_conn;
     
    388498}
    389499
     500static void ldap_connect_got_tls(struct tevent_req *subreq);
     501
    390502static void ldap_connect_got_sock(struct composite_context *ctx,
    391                                   struct ldap_connection *conn)
    392 {
    393         /* setup a handler for events on this socket */
    394         conn->event.fde = tevent_add_fd(conn->event.event_ctx, conn->sock,
    395                                         socket_get_fd(conn->sock),
    396                                         TEVENT_FD_READ, ldap_io_handler, conn);
    397         if (conn->event.fde == NULL) {
    398                 composite_error(ctx, NT_STATUS_INTERNAL_ERROR);
    399                 return;
    400         }
    401 
    402         tevent_fd_set_close_fn(conn->event.fde, socket_tevent_fd_close_fn);
    403         socket_set_flags(conn->sock, SOCKET_FLAG_NOCLOSE);
    404 
    405         talloc_steal(conn, conn->sock);
    406         if (conn->ldaps) {
    407                 struct socket_context *tls_socket;
    408                 char *cafile = lpcfg_tls_cafile(conn->sock, conn->lp_ctx);
    409 
    410                 if (!cafile || !*cafile) {
    411                         talloc_free(conn->sock);
    412                         return;
    413                 }
    414 
    415                 tls_socket = tls_init_client(conn->sock, conn->event.fde, cafile);
    416                 talloc_free(cafile);
    417 
    418                 if (tls_socket == NULL) {
    419                         talloc_free(conn->sock);
    420                         return;
    421                 }
    422 
    423                 conn->sock = talloc_steal(conn, tls_socket);
    424         }
    425 
    426         conn->packet = packet_init(conn);
    427         if (conn->packet == NULL) {
    428                 talloc_free(conn->sock);
    429                 return;
    430         }
    431 
    432         packet_set_private(conn->packet, conn);
    433         packet_set_socket(conn->packet, conn->sock);
    434         packet_set_callback(conn->packet, ldap_recv_handler);
    435         packet_set_full_request(conn->packet, ldap_full_packet);
    436         packet_set_error_handler(conn->packet, ldap_error_handler);
    437         packet_set_event_context(conn->packet, conn->event.event_ctx);
    438         packet_set_fde(conn->packet, conn->event.fde);
    439 /*      packet_set_serialise(conn->packet); */
    440 
    441         if (conn->ldaps) {
    442                 packet_set_unreliable_select(conn->packet);
    443         }
    444 
    445         composite_done(ctx);
     503                                  struct ldap_connection *conn)
     504{
     505        struct ldap_connect_state *state =
     506                talloc_get_type_abort(ctx->private_data,
     507                struct ldap_connect_state);
     508        struct tevent_req *subreq = NULL;
     509        int fd;
     510        int ret;
     511
     512        socket_set_flags(state->sock, SOCKET_FLAG_NOCLOSE);
     513        fd = socket_get_fd(state->sock);
     514        TALLOC_FREE(state->sock);
     515
     516        smb_set_close_on_exec(fd);
     517
     518        ret = set_blocking(fd, false);
     519        if (ret == -1) {
     520                NTSTATUS status = map_nt_error_from_unix_common(errno);
     521                composite_error(state->ctx, status);
     522                return;
     523        }
     524
     525        ret = tstream_bsd_existing_socket(state, fd, &state->raw);
     526        if (ret == -1) {
     527                NTSTATUS status = map_nt_error_from_unix_common(errno);
     528                composite_error(state->ctx, status);
     529                return;
     530        }
     531
     532        if (!conn->ldaps) {
     533                conn->sockets.raw = talloc_move(conn, &state->raw);
     534                conn->sockets.active = conn->sockets.raw;
     535                composite_done(state->ctx);
     536                return;
     537        }
     538
     539        subreq = tstream_tls_connect_send(state, state->ctx->event_ctx,
     540                                          state->raw, state->tls_params);
     541        if (composite_nomem(subreq, state->ctx)) {
     542                return;
     543        }
     544        tevent_req_set_callback(subreq, ldap_connect_got_tls, state);
     545}
     546
     547static void ldap_connect_got_tls(struct tevent_req *subreq)
     548{
     549        struct ldap_connect_state *state =
     550                tevent_req_callback_data(subreq,
     551                struct ldap_connect_state);
     552        int err;
     553        int ret;
     554
     555        ret = tstream_tls_connect_recv(subreq, &err, state, &state->tls);
     556        TALLOC_FREE(subreq);
     557        if (ret == -1) {
     558                NTSTATUS status = map_nt_error_from_unix_common(err);
     559                composite_error(state->ctx, status);
     560                return;
     561        }
     562
     563        talloc_steal(state->tls, state->tls_params);
     564
     565        state->conn->sockets.raw = talloc_move(state->conn, &state->raw);
     566        state->conn->sockets.tls = talloc_move(state->conn->sockets.raw,
     567                                               &state->tls);
     568        state->conn->sockets.active = state->conn->sockets.tls;
     569        composite_done(state->ctx);
    446570}
    447571
     
    449573{
    450574        struct ldap_connect_state *state =
    451                 talloc_get_type(ctx->async.private_data,
    452                                 struct ldap_connect_state);
     575                talloc_get_type_abort(ctx->async.private_data,
     576                struct ldap_connect_state);
    453577        struct ldap_connection *conn = state->conn;
    454578        uint16_t port;
    455         NTSTATUS status = socket_connect_multi_recv(ctx, state, &conn->sock,
     579        NTSTATUS status = socket_connect_multi_recv(ctx, state, &state->sock,
    456580                                                       &port);
    457581        if (!NT_STATUS_IS_OK(status)) {
     
    466590{
    467591        struct ldap_connect_state *state =
    468                 talloc_get_type(ctx->async.private_data,
    469                                 struct ldap_connect_state);
     592                talloc_get_type_abort(ctx->async.private_data,
     593                struct ldap_connect_state);
    470594        struct ldap_connection *conn = state->conn;
    471595
     
    534658        status = ldap_rebind(conn);
    535659        if ( ! NT_STATUS_IS_OK(status)) {
    536                 ldap_connection_dead(conn);
    537         }
     660                ldap_connection_dead(conn, status);
     661        }
     662}
     663
     664static void ldap_request_destructor_abandon(struct ldap_request *abandon)
     665{
     666        TALLOC_FREE(abandon);
    538667}
    539668
     
    542671{
    543672        if (req->state == LDAP_REQUEST_PENDING) {
     673                struct ldap_message msg = {
     674                        .type = LDAP_TAG_AbandonRequest,
     675                        .r.AbandonRequest.messageid = req->messageid,
     676                };
     677                struct ldap_request *abandon = NULL;
     678
    544679                DLIST_REMOVE(req->conn->pending, req);
    545         }
     680
     681                abandon = ldap_request_send(req->conn, &msg);
     682                if (abandon == NULL) {
     683                        ldap_error_handler(req->conn, NT_STATUS_NO_MEMORY);
     684                        return 0;
     685                }
     686                abandon->async.fn = ldap_request_destructor_abandon;
     687                abandon->async.private_data = NULL;
     688        }
     689
    546690        return 0;
    547691}
    548692
    549 /*
    550   called on timeout of a ldap request
    551 */
    552 static void ldap_request_timeout(struct tevent_context *ev, struct tevent_timer *te,
    553                                       struct timeval t, void *private_data)
    554 {
    555         struct ldap_request *req = talloc_get_type(private_data, struct ldap_request);
    556         req->status = NT_STATUS_IO_TIMEOUT;
     693static void ldap_request_timeout_abandon(struct ldap_request *abandon)
     694{
     695        struct ldap_request *req =
     696                talloc_get_type_abort(abandon->async.private_data,
     697                struct ldap_request);
     698
    557699        if (req->state == LDAP_REQUEST_PENDING) {
    558700                DLIST_REMOVE(req->conn->pending, req);
     
    564706}
    565707
    566 
    567 /*
    568   called on completion of a failed ldap request
    569 */
    570 static void ldap_request_failed_complete(struct tevent_context *ev, struct tevent_timer *te,
     708/*
     709  called on timeout of a ldap request
     710*/
     711static void ldap_request_timeout(struct tevent_context *ev, struct tevent_timer *te,
    571712                                      struct timeval t, void *private_data)
    572713{
    573         struct ldap_request *req = talloc_get_type(private_data, struct ldap_request);
    574         if (req->async.fn) {
    575                 req->async.fn(req);
    576         }
    577 }
    578 
    579 /*
    580   called on completion of a one-way ldap request
    581 */
    582 static void ldap_request_oneway_complete(void *private_data)
    583 {
    584         struct ldap_request *req = talloc_get_type(private_data, struct ldap_request);
     714        struct ldap_request *req =
     715                talloc_get_type_abort(private_data,
     716                struct ldap_request);
     717
     718        req->status = NT_STATUS_IO_TIMEOUT;
    585719        if (req->state == LDAP_REQUEST_PENDING) {
     720                struct ldap_message msg = {
     721                        .type = LDAP_TAG_AbandonRequest,
     722                        .r.AbandonRequest.messageid = req->messageid,
     723                };
     724                struct ldap_request *abandon = NULL;
     725
     726                abandon = ldap_request_send(req->conn, &msg);
     727                if (abandon == NULL) {
     728                        ldap_error_handler(req->conn, NT_STATUS_NO_MEMORY);
     729                        return;
     730                }
     731                talloc_reparent(req->conn, req, abandon);
     732                abandon->async.fn = ldap_request_timeout_abandon;
     733                abandon->async.private_data = req;
    586734                DLIST_REMOVE(req->conn->pending, req);
     735                return;
    587736        }
    588737        req->state = LDAP_REQUEST_DONE;
     
    591740        }
    592741}
     742
     743
     744/*
     745  called on completion of a failed ldap request
     746*/
     747static void ldap_request_failed_complete(struct tevent_context *ev, struct tevent_timer *te,
     748                                      struct timeval t, void *private_data)
     749{
     750        struct ldap_request *req =
     751                talloc_get_type_abort(private_data,
     752                struct ldap_request);
     753
     754        if (req->async.fn) {
     755                req->async.fn(req);
     756        }
     757}
     758
     759static void ldap_request_written(struct tevent_req *subreq);
     760
    593761/*
    594762  send a ldap message - async interface
     
    599767        struct ldap_request *req;
    600768        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
    601         packet_send_callback_fn_t send_callback = NULL;
     769        struct tevent_req *subreq = NULL;
    602770
    603771        req = talloc_zero(conn, struct ldap_request);
    604772        if (req == NULL) return NULL;
    605773
    606         if (conn->sock == NULL) {
     774        if (conn->sockets.active == NULL) {
    607775                status = NT_STATUS_INVALID_CONNECTION;
    608776                goto failed;
     
    629797        }
    630798
    631         if (req->type == LDAP_TAG_AbandonRequest ||
    632             req->type == LDAP_TAG_UnbindRequest) {
    633                 send_callback = ldap_request_oneway_complete;
    634         }
    635 
    636         status = packet_send_callback(conn->packet, req->data,
    637                                       send_callback, req);
    638         if (!NT_STATUS_IS_OK(status)) {
    639                 goto failed;
    640         }
    641 
    642         req->state = LDAP_REQUEST_PENDING;
    643         DLIST_ADD(conn->pending, req);
    644 
    645799        /* put a timeout on the request */
    646800        req->time_event = tevent_add_timer(conn->event.event_ctx, req,
    647801                                           timeval_current_ofs(conn->timeout, 0),
    648802                                           ldap_request_timeout, req);
     803        if (req->time_event == NULL) {
     804                status = NT_STATUS_NO_MEMORY;
     805                goto failed;
     806        }
     807
     808        req->write_iov.iov_base = req->data.data;
     809        req->write_iov.iov_len = req->data.length;
     810
     811        subreq = tstream_writev_queue_send(req, conn->event.event_ctx,
     812                                           conn->sockets.active,
     813                                           conn->sockets.send_queue,
     814                                           &req->write_iov, 1);
     815        if (subreq == NULL) {
     816                status = NT_STATUS_NO_MEMORY;
     817                goto failed;
     818        }
     819        tevent_req_set_callback(subreq, ldap_request_written, req);
     820
     821        req->state = LDAP_REQUEST_PENDING;
     822        DLIST_ADD(conn->pending, req);
    649823
    650824        return req;
     
    659833}
    660834
     835static void ldap_request_written(struct tevent_req *subreq)
     836{
     837        struct ldap_request *req =
     838                tevent_req_callback_data(subreq,
     839                struct ldap_request);
     840        int err;
     841        ssize_t ret;
     842
     843        ret = tstream_writev_queue_recv(subreq, &err);
     844        TALLOC_FREE(subreq);
     845        if (ret == -1) {
     846                NTSTATUS error = map_nt_error_from_unix_common(err);
     847                ldap_error_handler(req->conn, error);
     848                return;
     849        }
     850
     851        if (req->type == LDAP_TAG_AbandonRequest ||
     852            req->type == LDAP_TAG_UnbindRequest)
     853        {
     854                if (req->state == LDAP_REQUEST_PENDING) {
     855                        DLIST_REMOVE(req->conn->pending, req);
     856                }
     857                req->state = LDAP_REQUEST_DONE;
     858                if (req->async.fn) {
     859                        req->async.fn(req);
     860                }
     861                return;
     862        }
     863
     864        ldap_connection_recv_next(req->conn);
     865}
     866
    661867
    662868/*
     
    668874        while (req->state < LDAP_REQUEST_DONE) {
    669875                if (tevent_loop_once(req->conn->event.event_ctx) != 0) {
     876                        req->state = LDAP_REQUEST_ERROR;
    670877                        req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR;
    671878                        break;
  • vendor/current/source4/libcli/ldap/ldap_client.h

    r740 r988  
    2121
    2222
     23#include "system/network.h" /* for struct iovec */
    2324#include "libcli/ldap/libcli_ldap.h"
    2425
     
    4041        NTSTATUS status;
    4142        DATA_BLOB data;
     43        struct iovec write_iov;
     44
    4245        struct {
    4346                void (*fn)(struct ldap_request *);
     
    5154/* main context for a ldap client connection */
    5255struct ldap_connection {
    53         struct socket_context *sock;
     56        struct {
     57                struct tstream_context *raw;
     58                struct tstream_context *tls;
     59                struct tstream_context *sasl;
     60                struct tstream_context *active;
     61
     62                struct tevent_queue *send_queue;
     63                struct tevent_req *recv_subreq;
     64        } sockets;
     65
    5466        struct loadparm_context *lp_ctx;
    5567
     
    90102        struct {
    91103                struct tevent_context *event_ctx;
    92                 struct tevent_fd *fde;
    93104        } event;
    94 
    95         struct packet_context *packet;
    96105};
    97106
  • vendor/current/source4/libcli/ldap/ldap_controls.c

    r740 r988  
    427427}
    428428
     429static bool decode_verify_name_request(void *mem_ctx, DATA_BLOB in, void *_out)
     430{
     431        void **out = (void **)_out;
     432        DATA_BLOB name;
     433        struct asn1_data *data = asn1_init(mem_ctx);
     434        struct ldb_verify_name_control *lvnc;
     435        int len;
     436
     437        if (!data) return false;
     438
     439        if (!asn1_load(data, in)) {
     440                return false;
     441        }
     442
     443        lvnc = talloc(mem_ctx, struct ldb_verify_name_control);
     444        if (!lvnc) {
     445                return false;
     446        }
     447
     448        if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
     449                return false;
     450        }
     451
     452        if (!asn1_read_Integer(data, &(lvnc->flags))) {
     453                return false;
     454        }
     455
     456        if (!asn1_read_OctetString(data, mem_ctx, &name)) {
     457                return false;
     458        }
     459
     460        if (name.length) {
     461                len = utf16_len_n(name.data, name.length);
     462                convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX,
     463                                        name.data, len,
     464                                        (void **)&lvnc->gc, &lvnc->gc_len);
     465
     466                if (!(lvnc->gc)) {
     467                        return false;
     468                }
     469        } else {
     470                lvnc->gc_len = 0;
     471                lvnc->gc = NULL;
     472        }
     473
     474        if (!asn1_end_tag(data)) {
     475                return false;
     476        }
     477
     478        *out = lvnc;
     479        return true;
     480}
     481
     482static bool encode_verify_name_request(void *mem_ctx, void *in, DATA_BLOB *out)
     483{
     484        struct ldb_verify_name_control *lvnc = talloc_get_type(in, struct ldb_verify_name_control);
     485        struct asn1_data *data = asn1_init(mem_ctx);
     486        DATA_BLOB gc_utf16;
     487
     488        if (!data) return false;
     489
     490        if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
     491                return false;
     492        }
     493
     494        if (!asn1_write_Integer(data, lvnc->flags)) {
     495                return false;
     496        }
     497
     498        if (lvnc->gc_len) {
     499                convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16,
     500                                                lvnc->gc, lvnc->gc_len,
     501                                                (void **)&gc_utf16.data, &gc_utf16.length);
     502                if (!asn1_write_OctetString(data, gc_utf16.data, gc_utf16.length)) {
     503                        return false;
     504                }
     505        } else {
     506                if (!asn1_write_OctetString(data, NULL, 0)) {
     507                        return false;
     508                }
     509        }
     510
     511        if (!asn1_pop_tag(data)) {
     512                return false;
     513        }
     514
     515        if (!asn1_extract_blob(data, mem_ctx, out)) {
     516                return false;
     517        }
     518
     519        talloc_free(data);
     520
     521        return true;
     522}
     523
    429524static bool decode_vlv_request(void *mem_ctx, DATA_BLOB in, void *_out)
    430525{
     
    622717        }
    623718
    624         *out = data_blob_talloc(mem_ctx, data->data, data->length);
    625         if (out->data == NULL) {
    626                 return false;
    627         }
     719        if (!asn1_extract_blob(data, mem_ctx, out)) {
     720                return false;
     721        }
     722
    628723        talloc_free(data);
    629724
     
    680775        }
    681776
    682         *out = data_blob_talloc(mem_ctx, data->data, data->length);
    683         if (out->data == NULL) {
    684                 return false;
    685         }
     777        if (!asn1_extract_blob(data, mem_ctx, out)) {
     778                return false;
     779        }
     780
    686781        talloc_free(data);
    687782
     
    715810        }
    716811
    717         *out = data_blob_talloc(mem_ctx, data->data, data->length);
    718         if (out->data == NULL) {
    719                 return false;
    720         }
     812        if (!asn1_extract_blob(data, mem_ctx, out)) {
     813                return false;
     814        }
     815
    721816        talloc_free(data);
    722817
     
    743838        }
    744839
    745         *out = data_blob_talloc(mem_ctx, data->data, data->length);
    746         if (out->data == NULL) {
    747                 return false;
    748         }
     840        if (!asn1_extract_blob(data, mem_ctx, out)) {
     841                return false;
     842        }
     843
    749844        talloc_free(data);
    750845
     
    771866        }
    772867
    773         *out = data_blob_talloc(mem_ctx, data->data, data->length);
    774         if (out->data == NULL) {
    775                 return false;
    776         }
     868        if (!asn1_extract_blob(data, mem_ctx, out)) {
     869                return false;
     870        }
     871
    777872        talloc_free(data);
    778873
     
    803898        }
    804899
    805         *out = data_blob_talloc(mem_ctx, data->data, data->length);
    806         if (out->data == NULL) {
    807                 return false;
    808         }
     900        if (!asn1_extract_blob(data, mem_ctx, out)) {
     901                return false;
     902        }
     903
    809904        talloc_free(data);
    810905
     
    841936        }
    842937
    843         *out = data_blob_talloc(mem_ctx, data->data, data->length);
    844         if (out->data == NULL) {
    845                 return false;
    846         }
     938        if (!asn1_extract_blob(data, mem_ctx, out)) {
     939                return false;
     940        }
     941
    847942        talloc_free(data);
    848943
     
    877972        }
    878973
    879         *out = data_blob_talloc(mem_ctx, data->data, data->length);
    880         if (out->data == NULL) {
    881                 return false;
    882         }
     974        if (!asn1_extract_blob(data, mem_ctx, out)) {
     975                return false;
     976        }
     977
    883978        talloc_free(data);
    884979
     
    9531048        }
    9541049
    955         *out = data_blob_talloc(mem_ctx, data->data, data->length);
    956         if (out->data == NULL) {
    957                 return false;
    958         }
     1050        if (!asn1_extract_blob(data, mem_ctx, out)) {
     1051                return false;
     1052        }
     1053
    9591054        talloc_free(data);
    9601055
     
    9951090        }
    9961091
    997         *out = data_blob_talloc(mem_ctx, data->data, data->length);
    998         if (out->data == NULL) {
    999                 return false;
    1000         }
     1092        if (!asn1_extract_blob(data, mem_ctx, out)) {
     1093                return false;
     1094        }
     1095
    10011096        talloc_free(data);
    10021097
     
    10351130                }
    10361131               
    1037                 asn1_pop_tag(data);
    1038                 asn1_pop_tag(data);
    1039         }
    1040         asn1_pop_tag(data);
    1041 
    1042         *out = data_blob_talloc(mem_ctx, data->data, data->length);
    1043         if (out->data == NULL) {
    1044                 return false;
    1045         }
     1132                if (!asn1_pop_tag(data)) {
     1133                        return false;
     1134                }
     1135                if (!asn1_pop_tag(data)) {
     1136                        return false;
     1137                }
     1138        }
     1139        if (!asn1_pop_tag(data)) {
     1140                return false;
     1141        }
     1142
     1143        if (!asn1_extract_blob(data, mem_ctx, out)) {
     1144                return false;
     1145        }
     1146
    10461147        talloc_free(data);
    10471148        return true;
     
    10871188                }
    10881189               
    1089                 asn1_read_OctetString_talloc(r[i], data, &r[i]->source_attribute);
    1090                 asn1_read_OctetString_talloc(r[i], data, &r[i]->dereferenced_dn);
     1190                if (!asn1_read_OctetString_talloc(r[i], data, &r[i]->source_attribute)) {
     1191                        return false;
     1192                }
     1193                if (!asn1_read_OctetString_talloc(r[i], data, &r[i]->dereferenced_dn)) {
     1194                        return false;
     1195                }
    10911196                if (asn1_peek_tag(data, ASN1_CONTEXT(0))) {
    10921197                        if (!asn1_start_tag(data, ASN1_CONTEXT(0))) {
    10931198                                return false;
    10941199                        }
    1095                        
    1096                         ldap_decode_attribs_bare(r, data, &r[i]->attributes,
    1097                                                  &r[i]->num_attributes);
    1098                        
     1200                        if (!ldap_decode_attribs_bare(r, data, &r[i]->attributes,
     1201                                                 &r[i]->num_attributes)) {
     1202                                return false;
     1203                        }
    10991204                        if (!asn1_end_tag(data)) {
    11001205                                return false;
     
    11521257        { LDB_CONTROL_ASQ_OID, decode_asq_control, encode_asq_control },
    11531258        { LDB_CONTROL_DIRSYNC_OID, decode_dirsync_request, encode_dirsync_request },
     1259        { LDB_CONTROL_DIRSYNC_EX_OID, decode_dirsync_request, encode_dirsync_request },
    11541260        { LDB_CONTROL_VLV_REQ_OID, decode_vlv_request, encode_vlv_request },
    11551261        { LDB_CONTROL_VLV_RESP_OID, decode_vlv_response, encode_vlv_response },
     
    11591265        { LDB_CONTROL_RELAX_OID, decode_flag_request, encode_flag_request },
    11601266        { DSDB_OPENLDAP_DEREFERENCE_CONTROL, decode_openldap_dereference, encode_openldap_dereference },
    1161 
    1162 /* DSDB_CONTROL_CURRENT_PARTITION_OID is internal only, and has no network representation */
     1267        { LDB_CONTROL_VERIFY_NAME_OID, decode_verify_name_request, encode_verify_name_request },
     1268
     1269        /* the following are internal only, with a network
     1270           representation */
     1271        { DSDB_CONTROL_BYPASS_PASSWORD_HASH_OID, decode_flag_request, encode_flag_request },
     1272
     1273        /* all the ones below are internal only, and have no network
     1274         * representation */
    11631275        { DSDB_CONTROL_CURRENT_PARTITION_OID, NULL, NULL },
    1164 /* DSDB_CONTROL_REPLICATED_UPDATE_OID is internal only, and has no network representation */
    11651276        { DSDB_CONTROL_REPLICATED_UPDATE_OID, NULL, NULL },
    1166 /* DSDB_CONTROL_DN_STORAGE_FORMAT_OID is internal only, and has no network representation */
    11671277        { DSDB_CONTROL_DN_STORAGE_FORMAT_OID, NULL, NULL },
    1168 /* LDB_CONTROL_RECALCULATE_SD_OID is internal only, and has no network representation */
    11691278        { LDB_CONTROL_RECALCULATE_SD_OID, NULL, NULL },
    1170 /* LDB_CONTROL_REVEAL_INTERNALS is internal only, and has no network representation */
    11711279        { LDB_CONTROL_REVEAL_INTERNALS, NULL, NULL },
    1172 /* LDB_CONTROL_AS_SYSTEM_OID is internal only, and has no network representation */
    11731280        { LDB_CONTROL_AS_SYSTEM_OID, NULL, NULL },
    1174 /* DSDB_CONTROL_PASSWORD_CHANGE_STATUS_OID is internal only, and has no network representation */
    11751281        { DSDB_CONTROL_PASSWORD_CHANGE_STATUS_OID, NULL, NULL },
    1176 /* DSDB_CONTROL_PASSWORD_HASH_VALUES_OID is internal only, and has no network representation */
    11771282        { DSDB_CONTROL_PASSWORD_HASH_VALUES_OID, NULL, NULL },
    1178 /* DSDB_CONTROL_PASSWORD_CHANGE_OID is internal only, and has no network representation */
    11791283        { DSDB_CONTROL_PASSWORD_CHANGE_OID, NULL, NULL },
    1180 /* DSDB_CONTROL_APPLY_LINKS is internal only, and has no network representation */
    11811284        { DSDB_CONTROL_APPLY_LINKS, NULL, NULL },
    1182 /* DSDB_CONTROL_BYPASS_PASSWORD_HASH_OID is internal only, and has an empty network representation */
    1183         { DSDB_CONTROL_BYPASS_PASSWORD_HASH_OID, decode_flag_request, encode_flag_request },
    1184 /* LDB_CONTROL_BYPASS_OPERATIONAL_OID is internal only, and has no network representation */
    11851285        { LDB_CONTROL_BYPASS_OPERATIONAL_OID, NULL, NULL },
    1186 /* DSDB_CONTROL_CHANGEREPLMETADATA_OID is internal only, and has no network representation */
    11871286        { DSDB_CONTROL_CHANGEREPLMETADATA_OID, NULL, NULL },
    1188 /* LDB_CONTROL_PROVISION_OID is internal only, and has no network representation */
    11891287        { LDB_CONTROL_PROVISION_OID, NULL, NULL },
    1190 /* DSDB_EXTENDED_REPLICATED_OBJECTS_OID is internal only, and has no network representation */
    11911288        { DSDB_EXTENDED_REPLICATED_OBJECTS_OID, NULL, NULL },
    1192 /* DSDB_EXTENDED_SCHEMA_UPDATE_NOW_OID is internal only, and has no network representation */
    11931289        { DSDB_EXTENDED_SCHEMA_UPDATE_NOW_OID, NULL, NULL },
    1194 /* DSDB_EXTENDED_ALLOCATE_RID_POOL is internal only, and has no network representation */
    11951290        { DSDB_EXTENDED_ALLOCATE_RID_POOL, NULL, NULL },
     1291        { DSDB_CONTROL_NO_GLOBAL_CATALOG, NULL, NULL },
     1292        { DSDB_EXTENDED_SCHEMA_UPGRADE_IN_PROGRESS_OID, NULL, NULL },
    11961293        { NULL, NULL, NULL }
    11971294};
  • vendor/current/source4/libcli/ldap/ldap_ildap.c

    r740 r988  
    120120                      struct ldap_message ***results)
    121121{
     122        NTSTATUS status;
    122123        struct ldb_parse_tree *tree = ldb_parse_tree(conn, expression);
    123         NTSTATUS status;
     124
     125        if (tree == NULL) {
     126                return NT_STATUS_INVALID_PARAMETER;
     127        }
    124128        status = ildap_search_bytree(conn, basedn, scope, tree, attrs,
    125129                                     attributesonly, control_req,
  • vendor/current/source4/libcli/ldap/wscript_build

    r740 r988  
    44                  source='ldap_client.c ldap_bind.c ldap_ildap.c ldap_controls.c',
    55                  autoproto='ldap_proto.h',
    6                   public_deps='errors tevent LIBPACKET',
    7                   public_headers='libcli_ldap.h:ldap-util.h',
    8                   deps='LIBCLI_COMPOSITE samba_socket NDR_SAMR LIBTLS LIBCLI_LDAP_NDR ndr LP_RESOLVE gensec LIBCLI_LDAP_MESSAGE',
     6                  public_deps='samba-errors tevent',
     7                  private_headers='libcli_ldap.h:ldap-util.h',
     8                  deps='cli_composite LIBSAMBA_TSOCKET samba_socket NDR_SAMR LIBTLS ndr LP_RESOLVE gensec cli-ldap-common',
    99                  private_library=True
    1010                  )
Note: See TracChangeset for help on using the changeset viewer.