Ignore:
Timestamp:
Nov 14, 2012, 12:59:34 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to 3.6.0

Location:
vendor/current/source4/ldap_server
Files:
1 added
32 deleted
5 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source4/ldap_server/ldap_backend.c

    r414 r740  
    2222#include "ldap_server/ldap_server.h"
    2323#include "../lib/util/dlinklist.h"
    24 #include "libcli/ldap/ldap.h"
    2524#include "auth/credentials/credentials.h"
    2625#include "auth/gensec/gensec.h"
     
    2827#include "smbd/service_stream.h"
    2928#include "dsdb/samdb/samdb.h"
    30 #include "lib/ldb/include/ldb_errors.h"
    31 #include "lib/ldb_wrap.h"
    32 
    33 #define VALID_DN_SYNTAX(dn) do {\
    34         if (!(dn)) {\
    35                 return NT_STATUS_NO_MEMORY;\
    36         } else if ( ! ldb_dn_validate(dn)) {\
    37                 result = LDAP_INVALID_DN_SYNTAX;\
    38                 map_ldb_error(local_ctx, LDB_ERR_INVALID_DN_SYNTAX, &errstr);\
    39                 goto reply;\
    40         }\
    41 } while(0)
     29#include <ldb_errors.h>
     30#include <ldb_module.h>
     31#include "ldb_wrap.h"
    4232
    4333static int map_ldb_error(TALLOC_CTX *mem_ctx, int ldb_err,
    44         const char **errstring)
     34        const char *add_err_string, const char **errstring)
    4535{
    4636        WERROR err;
     37
     38        /* Certain LDB modules need to return very special WERROR codes. Proof
     39         * for them here and if they exist skip the rest of the mapping. */
     40        if (add_err_string != NULL) {
     41                char *endptr;
     42                strtol(add_err_string, &endptr, 16);
     43                if (endptr != add_err_string) {
     44                        *errstring = add_err_string;
     45                        return ldb_err;
     46                }
     47        }
     48
     49        /* Otherwise we calculate here a generic, but appropriate WERROR. */
    4750
    4851        switch (ldb_err) {
     
    6063        break;
    6164        case LDB_ERR_SIZE_LIMIT_EXCEEDED:
    62                 err = WERR_DS_SIZE_LIMIT_EXCEEDED;
     65                err = WERR_DS_SIZELIMIT_EXCEEDED;
    6366        break;
    6467        case LDB_ERR_COMPARE_FALSE:
     
    166169        }
    167170
    168         *errstring = talloc_asprintf(mem_ctx, "%08x: %s", W_ERROR_V(err),
     171        *errstring = talloc_asprintf(mem_ctx, "%08X: %s", W_ERROR_V(err),
    169172                ldb_strerror(ldb_err));
     173        if (add_err_string != NULL) {
     174                *errstring = talloc_asprintf(mem_ctx, "%s - %s", *errstring,
     175                                             add_err_string);
     176        }
    170177       
    171178        /* result is 1:1 for now */
     
    178185NTSTATUS ldapsrv_backend_Init(struct ldapsrv_connection *conn)
    179186{
    180         conn->ldb = ldb_wrap_connect(conn,
     187        conn->ldb = samdb_connect(conn,
    181188                                     conn->connection->event.ctx,
    182189                                     conn->lp_ctx,
    183                                      lp_sam_url(conn->lp_ctx),
    184190                                     conn->session_info,
    185                                      samdb_credentials(conn, conn->connection->event.ctx, conn->lp_ctx),
    186                                      conn->global_catalog ? LDB_FLG_RDONLY : 0, NULL);
     191                                     conn->global_catalog ? LDB_FLG_RDONLY : 0);
    187192        if (conn->ldb == NULL) {
    188193                return NT_STATUS_INTERNAL_DB_CORRUPTION;
     
    194199                struct gensec_security_ops **ops
    195200                        = gensec_use_kerberos_mechs(conn, backends, conn->server_credentials);
    196                 int i, j = 0;
     201                unsigned int i, j = 0;
    197202                for (i = 0; ops && ops[i]; i++) {
    198                         if (!lp_parm_bool(conn->lp_ctx,  NULL, "gensec", ops[i]->name, ops[i]->enabled))
     203                        if (!lpcfg_parm_bool(conn->lp_ctx,  NULL, "gensec", ops[i]->name, ops[i]->enabled))
    199204                                continue;
    200205
     
    216221                }
    217222                talloc_unlink(conn, ops);
    218                 ldb_set_opaque(conn->ldb, "supportedSASLMechanims", sasl_mechs);
     223
     224                /* ldb can have a different lifetime to conn, so we
     225                   need to ensure that sasl_mechs lives as long as the
     226                   ldb does */
     227                talloc_steal(conn->ldb, sasl_mechs);
     228
     229                ldb_set_opaque(conn->ldb, "supportedSASLMechanisms", sasl_mechs);
    219230        }
    220231
     
    270281        ldapsrv_queue_reply(call, reply);
    271282        return NT_STATUS_OK;
     283}
     284
     285static int ldapsrv_add_with_controls(struct ldapsrv_call *call,
     286                                     const struct ldb_message *message,
     287                                     struct ldb_control **controls,
     288                                     void *context)
     289{
     290        struct ldb_context *ldb = call->conn->ldb;
     291        struct ldb_request *req;
     292        int ret;
     293
     294        ret = ldb_msg_sanity_check(ldb, message);
     295        if (ret != LDB_SUCCESS) {
     296                return ret;
     297        }
     298
     299        ret = ldb_build_add_req(&req, ldb, ldb,
     300                                        message,
     301                                        controls,
     302                                        context,
     303                                        ldb_modify_default_callback,
     304                                        NULL);
     305
     306        if (ret != LDB_SUCCESS) return ret;
     307
     308        ret = ldb_transaction_start(ldb);
     309        if (ret != LDB_SUCCESS) {
     310                return ret;
     311        }
     312
     313        if (!call->conn->is_privileged) {
     314                ldb_req_mark_untrusted(req);
     315        }
     316
     317        LDB_REQ_SET_LOCATION(req);
     318
     319        ret = ldb_request(ldb, req);
     320        if (ret == LDB_SUCCESS) {
     321                ret = ldb_wait(req->handle, LDB_WAIT_ALL);
     322        }
     323
     324        if (ret == LDB_SUCCESS) {
     325                ret = ldb_transaction_commit(ldb);
     326        }
     327        else {
     328                ldb_transaction_cancel(ldb);
     329        }
     330
     331        talloc_free(req);
     332        return ret;
     333}
     334
     335/* create and execute a modify request */
     336static int ldapsrv_mod_with_controls(struct ldapsrv_call *call,
     337                                     const struct ldb_message *message,
     338                                     struct ldb_control **controls,
     339                                     void *context)
     340{
     341        struct ldb_context *ldb = call->conn->ldb;
     342        struct ldb_request *req;
     343        int ret;
     344
     345        ret = ldb_msg_sanity_check(ldb, message);
     346        if (ret != LDB_SUCCESS) {
     347                return ret;
     348        }
     349
     350        ret = ldb_build_mod_req(&req, ldb, ldb,
     351                                        message,
     352                                        controls,
     353                                        context,
     354                                        ldb_modify_default_callback,
     355                                        NULL);
     356
     357        if (ret != LDB_SUCCESS) {
     358                return ret;
     359        }
     360
     361        ret = ldb_transaction_start(ldb);
     362        if (ret != LDB_SUCCESS) {
     363                return ret;
     364        }
     365
     366        if (!call->conn->is_privileged) {
     367                ldb_req_mark_untrusted(req);
     368        }
     369
     370        LDB_REQ_SET_LOCATION(req);
     371
     372        ret = ldb_request(ldb, req);
     373        if (ret == LDB_SUCCESS) {
     374                ret = ldb_wait(req->handle, LDB_WAIT_ALL);
     375        }
     376
     377        if (ret == LDB_SUCCESS) {
     378                ret = ldb_transaction_commit(ldb);
     379        }
     380        else {
     381                ldb_transaction_cancel(ldb);
     382        }
     383
     384        talloc_free(req);
     385        return ret;
     386}
     387
     388/* create and execute a delete request */
     389static int ldapsrv_del_with_controls(struct ldapsrv_call *call,
     390                                     struct ldb_dn *dn,
     391                                     struct ldb_control **controls,
     392                                     void *context)
     393{
     394        struct ldb_context *ldb = call->conn->ldb;
     395        struct ldb_request *req;
     396        int ret;
     397
     398        ret = ldb_build_del_req(&req, ldb, ldb,
     399                                        dn,
     400                                        controls,
     401                                        context,
     402                                        ldb_modify_default_callback,
     403                                        NULL);
     404
     405        if (ret != LDB_SUCCESS) return ret;
     406
     407        ret = ldb_transaction_start(ldb);
     408        if (ret != LDB_SUCCESS) {
     409                return ret;
     410        }
     411
     412        if (!call->conn->is_privileged) {
     413                ldb_req_mark_untrusted(req);
     414        }
     415
     416        LDB_REQ_SET_LOCATION(req);
     417
     418        ret = ldb_request(ldb, req);
     419        if (ret == LDB_SUCCESS) {
     420                ret = ldb_wait(req->handle, LDB_WAIT_ALL);
     421        }
     422
     423        if (ret == LDB_SUCCESS) {
     424                ret = ldb_transaction_commit(ldb);
     425        }
     426        else {
     427                ldb_transaction_cancel(ldb);
     428        }
     429
     430        talloc_free(req);
     431        return ret;
     432}
     433
     434static int ldapsrv_rename_with_controls(struct ldapsrv_call *call,
     435                                        struct ldb_dn *olddn,
     436                                        struct ldb_dn *newdn,
     437                                        struct ldb_control **controls,
     438                                        void *context)
     439{
     440        struct ldb_context *ldb = call->conn->ldb;
     441        struct ldb_request *req;
     442        int ret;
     443
     444        ret = ldb_build_rename_req(&req, ldb, ldb,
     445                                        olddn,
     446                                        newdn,
     447                                        NULL,
     448                                        context,
     449                                        ldb_modify_default_callback,
     450                                        NULL);
     451
     452        if (ret != LDB_SUCCESS) return ret;
     453
     454        ret = ldb_transaction_start(ldb);
     455        if (ret != LDB_SUCCESS) {
     456                return ret;
     457        }
     458
     459        if (!call->conn->is_privileged) {
     460                ldb_req_mark_untrusted(req);
     461        }
     462
     463        LDB_REQ_SET_LOCATION(req);
     464
     465        ret = ldb_request(ldb, req);
     466        if (ret == LDB_SUCCESS) {
     467                ret = ldb_wait(req->handle, LDB_WAIT_ALL);
     468        }
     469
     470        if (ret == LDB_SUCCESS) {
     471                ret = ldb_transaction_commit(ldb);
     472        }
     473        else {
     474                ldb_transaction_cancel(ldb);
     475        }
     476
     477        talloc_free(req);
     478        return ret;
    272479}
    273480
     
    293500        int result = -1;
    294501        int ldb_ret = -1;
    295         int i, j;
     502        unsigned int i, j;
    296503        int extended_type = 1;
    297504
     
    304511
    305512        basedn = ldb_dn_new(local_ctx, samdb, req->basedn);
    306         VALID_DN_SYNTAX(basedn);
     513        NT_STATUS_HAVE_NO_MEMORY(basedn);
    307514
    308515        DEBUG(10, ("SearchRequest: basedn: [%s]\n", req->basedn));
     
    327534                default:
    328535                        result = LDAP_PROTOCOL_ERROR;
    329                         map_ldb_error(local_ctx, LDB_ERR_PROTOCOL_ERROR,
     536                        map_ldb_error(local_ctx, LDB_ERR_PROTOCOL_ERROR, NULL,
    330537                                &errstr);
    331538                        errstr = talloc_asprintf(local_ctx,
     
    390597
    391598        ldb_set_timeout(samdb, lreq, req->timelimit);
     599
     600        if (!call->conn->is_privileged) {
     601                ldb_req_mark_untrusted(lreq);
     602        }
     603
     604        LDB_REQ_SET_LOCATION(lreq);
    392605
    393606        ldb_ret = ldb_request(samdb, lreq);
     
    432645                        ldapsrv_queue_reply(call, ent_r);
    433646                }
     647
     648                /* Send back referrals if they do exist (search operations) */
     649                if (res->refs != NULL) {
     650                        char **ref;
     651                        struct ldap_SearchResRef *ent_ref;
     652
     653                        for (ref = res->refs; *ref != NULL; ++ref) {
     654                                ent_r = ldapsrv_init_reply(call, LDAP_TAG_SearchResultReference);
     655                                NT_STATUS_HAVE_NO_MEMORY(ent_r);
     656
     657                                /* Better to have the whole referrals kept here,
     658                                 * than to find someone further up didn't put
     659                                 * a value in the right spot in the talloc tree
     660                                 */
     661                                talloc_steal(ent_r, *ref);
     662
     663                                ent_ref = &ent_r->msg->r.SearchResultReference;
     664                                ent_ref->referral = *ref;
     665
     666                                ldapsrv_queue_reply(call, ent_r);
     667                        }
     668                }
    434669        }
    435670
     
    455690        } else {
    456691                DEBUG(10,("SearchRequest: error\n"));
    457                 result = map_ldb_error(local_ctx, ldb_ret, &errstr);
     692                result = map_ldb_error(local_ctx, ldb_ret, ldb_errstring(samdb),
     693                                       &errstr);
    458694        }
    459695
     
    479715        int result = LDAP_SUCCESS;
    480716        int ldb_ret;
    481         int i,j;
     717        unsigned int i,j;
     718        struct ldb_result *res = NULL;
    482719
    483720        DEBUG(10, ("ModifyRequest"));
    484         DEBUGADD(10, (" dn: %s", req->dn));
     721        DEBUGADD(10, (" dn: %s\n", req->dn));
    485722
    486723        local_ctx = talloc_named(call, 0, "ModifyRequest local memory context");
     
    488725
    489726        dn = ldb_dn_new(local_ctx, samdb, req->dn);
    490         VALID_DN_SYNTAX(dn);
     727        NT_STATUS_HAVE_NO_MEMORY(dn);
    491728
    492729        DEBUG(10, ("ModifyRequest: dn: [%s]\n", req->dn));
     
    513750                                result = LDAP_PROTOCOL_ERROR;
    514751                                map_ldb_error(local_ctx,
    515                                         LDB_ERR_PROTOCOL_ERROR, &errstr);
     752                                        LDB_ERR_PROTOCOL_ERROR, NULL, &errstr);
    516753                                errstr = talloc_asprintf(local_ctx,
    517754                                        "%s. Invalid LDAP_MODIFY_* type", errstr);
     
    535772
    536773                                for (j=0; j < msg->elements[i].num_values; j++) {
    537                                         if (!(req->mods[i].attrib.values[j].length > 0)) {
    538                                                 result = LDAP_OTHER;
    539 
    540                                                 map_ldb_error(local_ctx,
    541                                                         LDB_ERR_OTHER, &errstr);
    542                                                 errstr = talloc_asprintf(local_ctx,
    543                                                         "%s. Empty attribute values not allowed", errstr);
    544                                                 goto reply;
    545                                         }
    546774                                        msg->elements[i].values[j].length = req->mods[i].attrib.values[j].length;
    547775                                        msg->elements[i].values[j].data = req->mods[i].attrib.values[j].data;                   
     
    549777                        }
    550778                }
    551         } else {
    552                 result = LDAP_OTHER;
    553                 map_ldb_error(local_ctx, LDB_ERR_OTHER, &errstr);
    554                 errstr = talloc_asprintf(local_ctx,
    555                         "%s. No mods are not allowed", errstr);
    556                 goto reply;
    557779        }
    558780
     
    562784
    563785        if (result == LDAP_SUCCESS) {
    564                 ldb_ret = ldb_modify(samdb, msg);
    565                 result = map_ldb_error(local_ctx, ldb_ret, &errstr);
    566         }
    567 
    568         modify_result = &modify_reply->msg->r.AddResponse;
     786                res = talloc_zero(local_ctx, struct ldb_result);
     787                NT_STATUS_HAVE_NO_MEMORY(res);
     788                ldb_ret = ldapsrv_mod_with_controls(call, msg, call->request->controls, res);
     789                result = map_ldb_error(local_ctx, ldb_ret, ldb_errstring(samdb),
     790                                       &errstr);
     791        }
     792
     793        modify_result = &modify_reply->msg->r.ModifyResponse;
    569794        modify_result->dn = NULL;
    570         modify_result->resultcode = result;
    571         modify_result->errormessage = (errstr?talloc_strdup(modify_reply, errstr):NULL);
    572         modify_result->referral = NULL;
    573 
     795        if ((res != NULL) && (res->refs != NULL)) {
     796                modify_result->resultcode = map_ldb_error(local_ctx,
     797                                                          LDB_ERR_REFERRAL,
     798                                                          NULL, &errstr);
     799                modify_result->errormessage = (errstr?talloc_strdup(modify_reply, errstr):NULL);
     800                modify_result->referral = talloc_strdup(call, *res->refs);
     801        } else {
     802                modify_result->resultcode = result;
     803                modify_result->errormessage = (errstr?talloc_strdup(modify_reply, errstr):NULL);
     804                modify_result->referral = NULL;
     805        }
    574806        talloc_free(local_ctx);
    575807
     
    591823        int result = LDAP_SUCCESS;
    592824        int ldb_ret;
    593         int i,j;
     825        unsigned int i,j;
     826        struct ldb_result *res = NULL;
    594827
    595828        DEBUG(10, ("AddRequest"));
    596         DEBUGADD(10, (" dn: %s", req->dn));
     829        DEBUGADD(10, (" dn: %s\n", req->dn));
    597830
    598831        local_ctx = talloc_named(call, 0, "AddRequest local memory context");
     
    600833
    601834        dn = ldb_dn_new(local_ctx, samdb, req->dn);
    602         VALID_DN_SYNTAX(dn);
     835        NT_STATUS_HAVE_NO_MEMORY(dn);
    603836
    604837        DEBUG(10, ("AddRequest: dn: [%s]\n", req->dn));
     
    629862
    630863                                for (j=0; j < msg->elements[i].num_values; j++) {
    631                                         if (!(req->attributes[i].values[j].length > 0)) {
    632                                                 result = LDAP_OTHER;
    633                                                 map_ldb_error(local_ctx,
    634                                                         LDB_ERR_OTHER, &errstr);
    635                                                 errstr = talloc_asprintf(local_ctx,
    636                                                         "%s. Empty attribute values not allowed", errstr);
    637                                                 goto reply;
    638                                         }
    639864                                        msg->elements[i].values[j].length = req->attributes[i].values[j].length;
    640865                                        msg->elements[i].values[j].data = req->attributes[i].values[j].data;                   
    641866                                }
    642                         } else {
    643                                 result = LDAP_OTHER;
    644                                 map_ldb_error(local_ctx, LDB_ERR_OTHER, &errstr);
    645                                 errstr = talloc_asprintf(local_ctx,
    646                                         "%s. No attribute values are not allowed", errstr);
    647                                 goto reply;
    648867                        }
    649868                }
    650         } else {
    651                 result = LDAP_OTHER;
    652                 map_ldb_error(local_ctx, LDB_ERR_OTHER, &errstr);
    653                 errstr = talloc_asprintf(local_ctx,
    654                         "%s. No attributes are not allowed", errstr);
    655                 goto reply;
    656         }
    657 
    658 reply:
     869        }
     870
    659871        add_reply = ldapsrv_init_reply(call, LDAP_TAG_AddResponse);
    660872        NT_STATUS_HAVE_NO_MEMORY(add_reply);
    661873
    662874        if (result == LDAP_SUCCESS) {
    663                 ldb_ret = ldb_add(samdb, msg);
    664                 result = map_ldb_error(local_ctx, ldb_ret, &errstr);
     875                res = talloc_zero(local_ctx, struct ldb_result);
     876                NT_STATUS_HAVE_NO_MEMORY(res);
     877                ldb_ret = ldapsrv_add_with_controls(call, msg, call->request->controls, res);
     878                result = map_ldb_error(local_ctx, ldb_ret, ldb_errstring(samdb),
     879                                       &errstr);
    665880        }
    666881
    667882        add_result = &add_reply->msg->r.AddResponse;
    668883        add_result->dn = NULL;
    669         add_result->resultcode = result;
    670         add_result->errormessage = (errstr?talloc_strdup(add_reply,errstr):NULL);
    671         add_result->referral = NULL;
    672 
     884        if ((res != NULL) && (res->refs != NULL)) {
     885                add_result->resultcode =  map_ldb_error(local_ctx,
     886                                                        LDB_ERR_REFERRAL, NULL,
     887                                                        &errstr);
     888                add_result->errormessage = (errstr?talloc_strdup(add_reply,errstr):NULL);
     889                add_result->referral = talloc_strdup(call, *res->refs);
     890        } else {
     891                add_result->resultcode = result;
     892                add_result->errormessage = (errstr?talloc_strdup(add_reply,errstr):NULL);
     893                add_result->referral = NULL;
     894        }
    673895        talloc_free(local_ctx);
    674896
     
    689911        int result = LDAP_SUCCESS;
    690912        int ldb_ret;
     913        struct ldb_result *res = NULL;
    691914
    692915        DEBUG(10, ("DelRequest"));
    693         DEBUGADD(10, (" dn: %s", req->dn));
     916        DEBUGADD(10, (" dn: %s\n", req->dn));
    694917
    695918        local_ctx = talloc_named(call, 0, "DelRequest local memory context");
     
    697920
    698921        dn = ldb_dn_new(local_ctx, samdb, req->dn);
    699         VALID_DN_SYNTAX(dn);
     922        NT_STATUS_HAVE_NO_MEMORY(dn);
    700923
    701924        DEBUG(10, ("DelRequest: dn: [%s]\n", req->dn));
    702925
    703 reply:
    704926        del_reply = ldapsrv_init_reply(call, LDAP_TAG_DelResponse);
    705927        NT_STATUS_HAVE_NO_MEMORY(del_reply);
    706928
    707929        if (result == LDAP_SUCCESS) {
    708                 ldb_ret = ldb_delete(samdb, dn);
    709                 result = map_ldb_error(local_ctx, ldb_ret, &errstr);
     930                res = talloc_zero(local_ctx, struct ldb_result);
     931                NT_STATUS_HAVE_NO_MEMORY(res);
     932                ldb_ret = ldapsrv_del_with_controls(call, dn, call->request->controls, res);
     933                result = map_ldb_error(local_ctx, ldb_ret, ldb_errstring(samdb),
     934                                       &errstr);
    710935        }
    711936
    712937        del_result = &del_reply->msg->r.DelResponse;
    713938        del_result->dn = NULL;
    714         del_result->resultcode = result;
    715         del_result->errormessage = (errstr?talloc_strdup(del_reply,errstr):NULL);
    716         del_result->referral = NULL;
     939        if ((res != NULL) && (res->refs != NULL)) {
     940                del_result->resultcode = map_ldb_error(local_ctx,
     941                                                       LDB_ERR_REFERRAL, NULL,
     942                                                       &errstr);
     943                del_result->errormessage = (errstr?talloc_strdup(del_reply,errstr):NULL);
     944                del_result->referral = talloc_strdup(call, *res->refs);
     945        } else {
     946                del_result->resultcode = result;
     947                del_result->errormessage = (errstr?talloc_strdup(del_reply,errstr):NULL);
     948                del_result->referral = NULL;
     949        }
    717950
    718951        talloc_free(local_ctx);
     
    734967        int result = LDAP_SUCCESS;
    735968        int ldb_ret;
     969        struct ldb_result *res = NULL;
    736970
    737971        DEBUG(10, ("ModifyDNRequest"));
    738972        DEBUGADD(10, (" dn: %s", req->dn));
    739         DEBUGADD(10, (" newrdn: %s", req->newrdn));
     973        DEBUGADD(10, (" newrdn: %s\n", req->newrdn));
    740974
    741975        local_ctx = talloc_named(call, 0, "ModifyDNRequest local memory context");
     
    743977
    744978        olddn = ldb_dn_new(local_ctx, samdb, req->dn);
    745         VALID_DN_SYNTAX(olddn);
     979        NT_STATUS_HAVE_NO_MEMORY(olddn);
    746980
    747981        newrdn = ldb_dn_new(local_ctx, samdb, req->newrdn);
    748         VALID_DN_SYNTAX(newrdn);
     982        NT_STATUS_HAVE_NO_MEMORY(newrdn);
    749983
    750984        DEBUG(10, ("ModifyDNRequest: olddn: [%s]\n", req->dn));
    751985        DEBUG(10, ("ModifyDNRequest: newrdn: [%s]\n", req->newrdn));
     986
     987        if (ldb_dn_get_comp_num(newrdn) == 0) {
     988                result = LDAP_PROTOCOL_ERROR;
     989                map_ldb_error(local_ctx, LDB_ERR_PROTOCOL_ERROR, NULL,
     990                              &errstr);
     991                goto reply;
     992        }
     993
     994        if (ldb_dn_get_comp_num(newrdn) > 1) {
     995                result = LDAP_NAMING_VIOLATION;
     996                map_ldb_error(local_ctx, LDB_ERR_NAMING_VIOLATION, NULL,
     997                              &errstr);
     998                goto reply;
     999        }
    7521000
    7531001        /* we can't handle the rename if we should not remove the old dn */
    7541002        if (!req->deleteolddn) {
    7551003                result = LDAP_UNWILLING_TO_PERFORM;
    756                 map_ldb_error(local_ctx, LDB_ERR_UNWILLING_TO_PERFORM, &errstr);
     1004                map_ldb_error(local_ctx, LDB_ERR_UNWILLING_TO_PERFORM, NULL,
     1005                              &errstr);
    7571006                errstr = talloc_asprintf(local_ctx,
    7581007                        "%s. Old RDN must be deleted", errstr);
     
    7611010
    7621011        if (req->newsuperior) {
     1012                DEBUG(10, ("ModifyDNRequest: newsuperior: [%s]\n", req->newsuperior));
    7631013                parentdn = ldb_dn_new(local_ctx, samdb, req->newsuperior);
    764                 VALID_DN_SYNTAX(parentdn);
    765                 DEBUG(10, ("ModifyDNRequest: newsuperior: [%s]\n", req->newsuperior));
    766                
    767                 if (ldb_dn_get_comp_num(parentdn) < 1) {
    768                         result = LDAP_AFFECTS_MULTIPLE_DSAS;
    769                         map_ldb_error(local_ctx, LDB_ERR_AFFECTS_MULTIPLE_DSAS,
    770                                 &errstr);
    771                         errstr = talloc_asprintf(local_ctx,
    772                                 "%s. Error new Superior DN invalid", errstr);
    773                         goto reply;
    774                 }
    7751014        }
    7761015
    7771016        if (!parentdn) {
    7781017                parentdn = ldb_dn_get_parent(local_ctx, olddn);
    779                 NT_STATUS_HAVE_NO_MEMORY(parentdn);
    780         }
    781 
    782         if ( ! ldb_dn_add_child_fmt(parentdn,
    783                                 "%s=%s",
    784                                 ldb_dn_get_rdn_name(newrdn),
    785                                 (char *)ldb_dn_get_rdn_val(newrdn)->data)) {
     1018        }
     1019        if (!parentdn) {
     1020                result = LDAP_NO_SUCH_OBJECT;
     1021                map_ldb_error(local_ctx, LDB_ERR_NO_SUCH_OBJECT, NULL, &errstr);
     1022                goto reply;
     1023        }
     1024
     1025        if ( ! ldb_dn_add_child(parentdn, newrdn)) {
    7861026                result = LDAP_OTHER;
     1027                map_ldb_error(local_ctx, LDB_ERR_OTHER, NULL, &errstr);
    7871028                goto reply;
    7881029        }
     
    7941035
    7951036        if (result == LDAP_SUCCESS) {
    796                 ldb_ret = ldb_rename(samdb, olddn, newdn);
    797                 result = map_ldb_error(local_ctx, ldb_ret, &errstr);
     1037                res = talloc_zero(local_ctx, struct ldb_result);
     1038                NT_STATUS_HAVE_NO_MEMORY(res);
     1039                ldb_ret = ldapsrv_rename_with_controls(call, olddn, newdn, call->request->controls, res);
     1040                result = map_ldb_error(local_ctx, ldb_ret, ldb_errstring(samdb),
     1041                                       &errstr);
    7981042        }
    7991043
    8001044        modifydn = &modifydn_r->msg->r.ModifyDNResponse;
    8011045        modifydn->dn = NULL;
    802         modifydn->resultcode = result;
    803         modifydn->errormessage = (errstr?talloc_strdup(modifydn_r,errstr):NULL);
    804         modifydn->referral = NULL;
     1046        if ((res != NULL) && (res->refs != NULL)) {
     1047                modifydn->resultcode = map_ldb_error(local_ctx,
     1048                                                     LDB_ERR_REFERRAL, NULL,
     1049                                                     &errstr);;
     1050                modifydn->errormessage = (errstr?talloc_strdup(modifydn_r,errstr):NULL);
     1051                modifydn->referral = talloc_strdup(call, *res->refs);
     1052        } else {
     1053                modifydn->resultcode = result;
     1054                modifydn->errormessage = (errstr?talloc_strdup(modifydn_r,errstr):NULL);
     1055                modifydn->referral = NULL;
     1056        }
    8051057
    8061058        talloc_free(local_ctx);
     
    8261078
    8271079        DEBUG(10, ("CompareRequest"));
    828         DEBUGADD(10, (" dn: %s", req->dn));
     1080        DEBUGADD(10, (" dn: %s\n", req->dn));
    8291081
    8301082        local_ctx = talloc_named(call, 0, "CompareRequest local_memory_context");
     
    8321084
    8331085        dn = ldb_dn_new(local_ctx, samdb, req->dn);
    834         VALID_DN_SYNTAX(dn);
     1086        NT_STATUS_HAVE_NO_MEMORY(dn);
    8351087
    8361088        DEBUG(10, ("CompareRequest: dn: [%s]\n", req->dn));
     
    8431095        attrs[0] = NULL;
    8441096
    845 reply:
    8461097        compare_r = ldapsrv_init_reply(call, LDAP_TAG_CompareResponse);
    8471098        NT_STATUS_HAVE_NO_MEMORY(compare_r);
     
    8511102                                     dn, LDB_SCOPE_BASE, attrs, "%s", filter);
    8521103                if (ldb_ret != LDB_SUCCESS) {
    853                         result = map_ldb_error(local_ctx, ldb_ret, &errstr);
     1104                        result = map_ldb_error(local_ctx, ldb_ret,
     1105                                               ldb_errstring(samdb), &errstr);
    8541106                        DEBUG(10,("CompareRequest: error: %s\n", errstr));
    8551107                } else if (res->count == 0) {
     
    8631115                } else if (res->count > 1) {
    8641116                        result = LDAP_OTHER;
    865                         map_ldb_error(local_ctx, LDB_ERR_OTHER, &errstr);
     1117                        map_ldb_error(local_ctx, LDB_ERR_OTHER, NULL, &errstr);
    8661118                        errstr = talloc_asprintf(local_ctx,
    8671119                                "%s. Too many objects match!", errstr);
     
    8911143NTSTATUS ldapsrv_do_call(struct ldapsrv_call *call)
    8921144{
    893         int i;
     1145        unsigned int i;
    8941146        struct ldap_message *msg = call->request;
    8951147        /* Check for undecoded critical extensions */
     
    9251177                return ldapsrv_ExtendedRequest(call);
    9261178        default:
    927                 return ldapsrv_unwilling(call, 2);
    928         }
    929 }
     1179                return ldapsrv_unwilling(call, LDAP_PROTOCOL_ERROR);
     1180        }
     1181}
  • vendor/current/source4/ldap_server/ldap_bind.c

    r414 r740  
    2121#include "ldap_server/ldap_server.h"
    2222#include "auth/auth.h"
    23 #include "libcli/ldap/ldap.h"
    2423#include "smbd/service.h"
    25 #include "lib/ldb/include/ldb.h"
    26 #include "lib/ldb/include/ldb_errors.h"
     24#include <ldb.h>
     25#include <ldb_errors.h>
    2726#include "dsdb/samdb/samdb.h"
    2827#include "auth/gensec/gensec.h"
     28#include "auth/gensec/gensec_tstream.h"
    2929#include "param/param.h"
     30#include "../lib/util/tevent_ntstatus.h"
    3031
    3132static NTSTATUS ldapsrv_BindSimple(struct ldapsrv_call *call)
     
    5354                                                  nt4_domain, nt4_account,
    5455                                                  req->creds.password,
     56                                                  MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
     57                                                  MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT,
    5558                                                  &session_info);
    5659        }
     
    6568                errstr = NULL;
    6669
    67                 talloc_free(call->conn->session_info);
     70                talloc_unlink(call->conn, call->conn->session_info);
    6871                call->conn->session_info = session_info;
    6972                talloc_steal(call->conn, session_info);
    7073
    7174                /* don't leak the old LDB */
    72                 talloc_free(call->conn->ldb);
     75                talloc_unlink(call->conn, call->conn->ldb);
    7376
    7477                status = ldapsrv_backend_Init(call->conn);             
     
    7982                }
    8083        } else {
    81                 status = auth_nt_status_squash(status);
     84                status = nt_status_squash(status);
    8285
    8386                result = LDAP_INVALID_CREDENTIALS;
     
    9699}
    97100
    98 struct ldapsrv_sasl_context {
     101struct ldapsrv_sasl_postprocess_context {
    99102        struct ldapsrv_connection *conn;
    100         struct socket_context *sasl_socket;
     103        struct tstream_context *sasl;
    101104};
    102105
    103 static void ldapsrv_set_sasl(void *private_data)
    104 {
    105         struct ldapsrv_sasl_context *ctx = talloc_get_type(private_data, struct ldapsrv_sasl_context);
    106         talloc_steal(ctx->conn->connection, ctx->sasl_socket);
    107         talloc_unlink(ctx->conn->connection, ctx->conn->connection->socket);
    108 
    109         ctx->conn->sockets.sasl = ctx->sasl_socket;
    110         ctx->conn->connection->socket = ctx->sasl_socket;
    111         packet_set_socket(ctx->conn->packet, ctx->conn->connection->socket);
     106struct ldapsrv_sasl_postprocess_state {
     107        uint8_t dummy;
     108};
     109
     110static struct tevent_req *ldapsrv_sasl_postprocess_send(TALLOC_CTX *mem_ctx,
     111                                                struct tevent_context *ev,
     112                                                void *private_data)
     113{
     114        struct ldapsrv_sasl_postprocess_context *context =
     115                talloc_get_type_abort(private_data,
     116                struct ldapsrv_sasl_postprocess_context);
     117        struct tevent_req *req;
     118        struct ldapsrv_sasl_postprocess_state *state;
     119
     120        req = tevent_req_create(mem_ctx, &state,
     121                                struct ldapsrv_sasl_postprocess_state);
     122        if (req == NULL) {
     123                return NULL;
     124        }
     125
     126        TALLOC_FREE(context->conn->sockets.sasl);
     127        context->conn->sockets.sasl = talloc_move(context->conn, &context->sasl);
     128        context->conn->sockets.active = context->conn->sockets.sasl;
     129
     130        tevent_req_done(req);
     131        return tevent_req_post(req, ev);
     132}
     133
     134static NTSTATUS ldapsrv_sasl_postprocess_recv(struct tevent_req *req)
     135{
     136        return tevent_req_simple_recv_ntstatus(req);
    112137}
    113138
     
    154179                                                 nt_errstr(status));
    155180                } else {
    156                
     181
    157182                        gensec_want_feature(conn->gensec, GENSEC_FEATURE_SIGN);
    158183                        gensec_want_feature(conn->gensec, GENSEC_FEATURE_SEAL);
     
    195220        } else if (NT_STATUS_IS_OK(status)) {
    196221                struct auth_session_info *old_session_info=NULL;
    197                 struct ldapsrv_sasl_context *ctx;
     222                struct ldapsrv_sasl_postprocess_context *context = NULL;
    198223
    199224                result = LDAP_SUCCESS;
    200225                errstr = NULL;
    201226
    202                 ctx = talloc(call, struct ldapsrv_sasl_context);
    203 
    204                 if (!ctx) {
    205                         status = NT_STATUS_NO_MEMORY;
    206                 } else {
    207                         ctx->conn = conn;
    208                         status = gensec_socket_init(conn->gensec,
    209                                                     conn->connection,
    210                                                     conn->connection->socket,
    211                                                     conn->connection->event.ctx,
    212                                                     stream_io_handler_callback,
    213                                                     conn->connection,
    214                                                     &ctx->sasl_socket);
    215                 }
    216 
    217                 if (!ctx || !NT_STATUS_IS_OK(status)) {
     227                if (gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN) ||
     228                    gensec_have_feature(conn->gensec, GENSEC_FEATURE_SEAL)) {
     229
     230                        context = talloc(call, struct ldapsrv_sasl_postprocess_context);
     231
     232                        if (!context) {
     233                                status = NT_STATUS_NO_MEMORY;
     234                        }
     235                }
     236
     237                if (context && conn->sockets.tls) {
     238                        TALLOC_FREE(context);
     239                        status = NT_STATUS_NOT_SUPPORTED;
     240                        result = LDAP_UNWILLING_TO_PERFORM;
     241                        errstr = talloc_asprintf(reply,
     242                                                 "SASL:[%s]: Sign or Seal are not allowed if TLS is used",
     243                                                 req->creds.SASL.mechanism);
     244                }
     245
     246                if (context && conn->sockets.sasl) {
     247                        TALLOC_FREE(context);
     248                        status = NT_STATUS_NOT_SUPPORTED;
     249                        result = LDAP_UNWILLING_TO_PERFORM;
     250                        errstr = talloc_asprintf(reply,
     251                                                 "SASL:[%s]: Sign or Seal are not allowed if SASL encryption has already been set up",
     252                                                 req->creds.SASL.mechanism);
     253                }
     254
     255                if (context) {
     256                        context->conn = conn;
     257                        status = gensec_create_tstream(context,
     258                                                       context->conn->gensec,
     259                                                       context->conn->sockets.raw,
     260                                                       &context->sasl);
     261                        if (NT_STATUS_IS_OK(status)) {
     262                                if (!talloc_reference(context->sasl, conn->gensec)) {
     263                                        status = NT_STATUS_NO_MEMORY;
     264                                }
     265                        }
     266                }
     267
     268                if (result != LDAP_SUCCESS) {
     269                        conn->session_info = old_session_info;
     270                } else if (!NT_STATUS_IS_OK(status)) {
    218271                        conn->session_info = old_session_info;
    219272                        result = LDAP_OPERATIONS_ERROR;
     
    223276                } else {
    224277
    225                         call->send_callback = ldapsrv_set_sasl;
    226                         call->send_private = ctx;
    227                
    228278                        old_session_info = conn->session_info;
    229279                        conn->session_info = NULL;
     
    236286                                                         req->creds.SASL.mechanism, nt_errstr(status));
    237287                        } else {
    238                                 talloc_free(old_session_info);
     288                                talloc_unlink(conn, old_session_info);
    239289                                talloc_steal(conn, conn->session_info);
    240290                               
    241291                                /* don't leak the old LDB */
    242                                 talloc_free(conn->ldb);
     292                                talloc_unlink(conn, conn->ldb);
    243293                               
    244294                                status = ldapsrv_backend_Init(conn);           
     
    253303                        }
    254304                }
     305
     306                if (NT_STATUS_IS_OK(status) && context) {
     307                        call->postprocess_send = ldapsrv_sasl_postprocess_send;
     308                        call->postprocess_recv = ldapsrv_sasl_postprocess_recv;
     309                        call->postprocess_private = context;
     310                }
     311                talloc_unlink(conn, conn->gensec);
     312                conn->gensec = NULL;
    255313        } else {
    256                 status = auth_nt_status_squash(status);
     314                status = nt_status_squash(status);
    257315                if (result == 0) {
    258316                        result = LDAP_INVALID_CREDENTIALS;
    259317                        errstr = talloc_asprintf(reply, "SASL:[%s]: %s", req->creds.SASL.mechanism, nt_errstr(status));
    260318                }
     319                talloc_unlink(conn, conn->gensec);
     320                conn->gensec = NULL;
    261321        }
    262322
  • vendor/current/source4/ldap_server/ldap_extended.c

    r414 r740  
    2121#include "ldap_server/ldap_server.h"
    2222#include "../lib/util/dlinklist.h"
    23 #include "libcli/ldap/ldap.h"
    2423#include "lib/tls/tls.h"
    2524#include "smbd/service_stream.h"
    26 
    27 struct ldapsrv_starttls_context {
     25#include "../lib/util/tevent_ntstatus.h"
     26
     27struct ldapsrv_starttls_postprocess_context {
    2828        struct ldapsrv_connection *conn;
    29         struct socket_context *tls_socket;
    30 };
    31 
    32 static void ldapsrv_start_tls(void *private_data)
    33 {
    34         struct ldapsrv_starttls_context *ctx = talloc_get_type(private_data, struct ldapsrv_starttls_context);
    35         talloc_steal(ctx->conn->connection, ctx->tls_socket);
    36 
    37         ctx->conn->sockets.tls = ctx->tls_socket;
    38         ctx->conn->connection->socket = ctx->tls_socket;
    39         packet_set_socket(ctx->conn->packet, ctx->conn->connection->socket);
    40         packet_set_unreliable_select(ctx->conn->packet);
     29};
     30
     31struct ldapsrv_starttls_postprocess_state {
     32        struct ldapsrv_connection *conn;
     33};
     34
     35static void ldapsrv_starttls_postprocess_done(struct tevent_req *subreq);
     36
     37static struct tevent_req *ldapsrv_starttls_postprocess_send(TALLOC_CTX *mem_ctx,
     38                                                struct tevent_context *ev,
     39                                                void *private_data)
     40{
     41        struct ldapsrv_starttls_postprocess_context *context =
     42                talloc_get_type_abort(private_data,
     43                struct ldapsrv_starttls_postprocess_context);
     44        struct ldapsrv_connection *conn = context->conn;
     45        struct tevent_req *req;
     46        struct ldapsrv_starttls_postprocess_state *state;
     47        struct tevent_req *subreq;
     48
     49        req = tevent_req_create(mem_ctx, &state,
     50                                struct ldapsrv_starttls_postprocess_state);
     51        if (req == NULL) {
     52                return NULL;
     53        }
     54
     55        state->conn = conn;
     56
     57        subreq = tstream_tls_accept_send(conn,
     58                                         conn->connection->event.ctx,
     59                                         conn->sockets.raw,
     60                                         conn->service->tls_params);
     61        if (tevent_req_nomem(subreq, req)) {
     62                return tevent_req_post(req, ev);
     63        }
     64        tevent_req_set_callback(subreq, ldapsrv_starttls_postprocess_done, req);
     65
     66        return req;
     67}
     68
     69static void ldapsrv_starttls_postprocess_done(struct tevent_req *subreq)
     70{
     71        struct tevent_req *req =
     72                tevent_req_callback_data(subreq,
     73                struct tevent_req);
     74        struct ldapsrv_starttls_postprocess_state *state =
     75                tevent_req_data(req,
     76                struct ldapsrv_starttls_postprocess_state);
     77        struct ldapsrv_connection *conn = state->conn;
     78        int ret;
     79        int sys_errno;
     80
     81        ret = tstream_tls_accept_recv(subreq, &sys_errno,
     82                                      conn, &conn->sockets.tls);
     83        TALLOC_FREE(subreq);
     84        if (ret == -1) {
     85                NTSTATUS status = map_nt_error_from_unix(sys_errno);
     86
     87                DEBUG(1,("ldapsrv_starttls_postprocess_done: accept_tls_loop: "
     88                         "tstream_tls_accept_recv() - %d:%s => %s",
     89                         sys_errno, strerror(sys_errno), nt_errstr(status)));
     90
     91                tevent_req_nterror(req, status);
     92                return;
     93        }
     94
     95        conn->sockets.active = conn->sockets.tls;
     96
     97        tevent_req_done(req);
     98}
     99
     100static NTSTATUS ldapsrv_starttls_postprocess_recv(struct tevent_req *req)
     101{
     102        return tevent_req_simple_recv_ntstatus(req);
    41103}
    42104
     
    45107                                 const char **errstr)
    46108{
    47         struct ldapsrv_starttls_context *ctx;
     109        struct ldapsrv_starttls_postprocess_context *context;
    48110
    49111        (*errstr) = NULL;
     
    60122        }
    61123
    62         ctx = talloc(call, struct ldapsrv_starttls_context);
    63         NT_STATUS_HAVE_NO_MEMORY(ctx);
    64 
    65         ctx->conn = call->conn;
    66         ctx->tls_socket = tls_init_server(call->conn->service->tls_params,
    67                                           call->conn->connection->socket,
    68                                           call->conn->connection->event.fde,
    69                                           NULL);
    70         if (!ctx->tls_socket) {
    71                 (*errstr) = talloc_asprintf(reply, "START-TLS: Failed to setup TLS socket");
     124        if (call->conn->sockets.sasl) {
     125                (*errstr) = talloc_asprintf(reply, "START-TLS: SASL is already enabled on this LDAP session");
    72126                return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR);
    73127        }
    74128
    75         call->send_callback = ldapsrv_start_tls;
    76         call->send_private  = ctx;
     129        context = talloc(call, struct ldapsrv_starttls_postprocess_context);
     130        NT_STATUS_HAVE_NO_MEMORY(context);
     131
     132        context->conn = call->conn;
     133
     134        call->postprocess_send = ldapsrv_starttls_postprocess_send;
     135        call->postprocess_recv = ldapsrv_starttls_postprocess_recv;
     136        call->postprocess_private = context;
    77137
    78138        reply->msg->r.ExtendedResponse.response.resultcode = LDAP_SUCCESS;
     
    105165        const char *error_str = NULL;
    106166        NTSTATUS status = NT_STATUS_OK;
    107         uint32_t i;
     167        unsigned int i;
    108168
    109169        DEBUG(10, ("Extended\n"));
  • vendor/current/source4/ldap_server/ldap_server.c

    r414 r740  
    2323
    2424#include "includes.h"
     25#include "system/network.h"
    2526#include "lib/events/events.h"
    2627#include "auth/auth.h"
     
    3637#include "lib/tls/tls.h"
    3738#include "lib/messaging/irpc.h"
    38 #include "lib/ldb/include/ldb.h"
    39 #include "lib/ldb/include/ldb_errors.h"
    40 #include "libcli/ldap/ldap.h"
     39#include <ldb.h>
     40#include <ldb_errors.h>
    4141#include "libcli/ldap/ldap_proto.h"
    4242#include "system/network.h"
     
    4444#include "dsdb/samdb/samdb.h"
    4545#include "param/param.h"
     46#include "../lib/tsocket/tsocket.h"
     47#include "../lib/util/tevent_ntstatus.h"
     48#include "../libcli/util/tstream.h"
     49
     50static void ldapsrv_terminate_connection_done(struct tevent_req *subreq);
     51
    4652/*
    4753  close the socket and shutdown a server_context
    4854*/
    49 void ldapsrv_terminate_connection(struct ldapsrv_connection *conn,
     55static void ldapsrv_terminate_connection(struct ldapsrv_connection *conn,
    5056                                         const char *reason)
    5157{
    52         packet_recv_disable(conn->packet);
    53         TALLOC_FREE(conn->packet);
     58        struct tevent_req *subreq;
     59
     60        if (conn->limits.reason) {
     61                return;
     62        }
     63
     64        conn->limits.endtime = timeval_current_ofs(0, 500);
     65
     66        tevent_queue_stop(conn->sockets.send_queue);
     67        if (conn->active_call) {
     68                tevent_req_cancel(conn->active_call);
     69                conn->active_call = NULL;
     70        }
     71
     72        conn->limits.reason = talloc_strdup(conn, reason);
     73        if (conn->limits.reason == NULL) {
     74                TALLOC_FREE(conn->sockets.tls);
     75                TALLOC_FREE(conn->sockets.sasl);
     76                TALLOC_FREE(conn->sockets.raw);
     77                stream_terminate_connection(conn->connection, reason);
     78                return;
     79        }
     80
     81        subreq = tstream_disconnect_send(conn,
     82                                         conn->connection->event.ctx,
     83                                         conn->sockets.active);
     84        if (subreq == NULL) {
     85                TALLOC_FREE(conn->sockets.tls);
     86                TALLOC_FREE(conn->sockets.sasl);
     87                TALLOC_FREE(conn->sockets.raw);
     88                stream_terminate_connection(conn->connection, reason);
     89                return;
     90        }
     91        tevent_req_set_endtime(subreq,
     92                               conn->connection->event.ctx,
     93                               conn->limits.endtime);
     94        tevent_req_set_callback(subreq, ldapsrv_terminate_connection_done, conn);
     95}
     96
     97static void ldapsrv_terminate_connection_done(struct tevent_req *subreq)
     98{
     99        struct ldapsrv_connection *conn =
     100                tevent_req_callback_data(subreq,
     101                struct ldapsrv_connection);
     102        int ret;
     103        int sys_errno;
     104
     105        ret = tstream_disconnect_recv(subreq, &sys_errno);
     106        TALLOC_FREE(subreq);
     107
     108        if (conn->sockets.active == conn->sockets.raw) {
     109                TALLOC_FREE(conn->sockets.tls);
     110                TALLOC_FREE(conn->sockets.sasl);
     111                TALLOC_FREE(conn->sockets.raw);
     112                stream_terminate_connection(conn->connection,
     113                                            conn->limits.reason);
     114                return;
     115        }
     116
    54117        TALLOC_FREE(conn->sockets.tls);
    55         stream_terminate_connection(conn->connection, reason);
    56 }
    57 
    58 /*
    59   handle packet errors
    60 */
    61 static void ldapsrv_error_handler(void *private_data, NTSTATUS status)
    62 {
    63         struct ldapsrv_connection *conn = talloc_get_type(private_data,
    64                                                           struct ldapsrv_connection);
    65         ldapsrv_terminate_connection(conn, nt_errstr(status));
    66 }
    67 
    68 /*
    69   process a decoded ldap message
    70 */
    71 static void ldapsrv_process_message(struct ldapsrv_connection *conn,
    72                                     struct ldap_message *msg)
    73 {
    74         struct ldapsrv_call *call;
    75         NTSTATUS status;
    76         DATA_BLOB blob;
    77 
    78         call = talloc(conn, struct ldapsrv_call);
    79         if (!call) {
    80                 ldapsrv_terminate_connection(conn, "no memory");
    81                 return;         
    82         }
    83 
    84         call->request = talloc_steal(call, msg);
    85         call->conn = conn;
    86         call->replies = NULL;
    87         call->send_callback = NULL;
    88         call->send_private = NULL;
    89 
    90         /* make the call */
    91         status = ldapsrv_do_call(call);
    92         if (!NT_STATUS_IS_OK(status)) {
    93                 talloc_free(call);
    94                 return;
    95         }
    96 
    97         blob = data_blob(NULL, 0);
    98 
    99         if (call->replies == NULL) {
    100                 talloc_free(call);
    101                 return;
    102         }
    103 
    104         /* build all the replies into a single blob */
    105         while (call->replies) {
    106                 DATA_BLOB b;
    107                 bool ret;
    108 
    109                 msg = call->replies->msg;
    110                 if (!ldap_encode(msg, samba_ldap_control_handlers(), &b, call)) {
    111                         DEBUG(0,("Failed to encode ldap reply of type %d\n", msg->type));
    112                         talloc_free(call);
    113                         return;
    114                 }
    115 
    116                 ret = data_blob_append(call, &blob, b.data, b.length);
    117                 data_blob_free(&b);
    118 
    119                 talloc_set_name_const(blob.data, "Outgoing, encoded LDAP packet");
    120 
    121                 if (!ret) {
    122                         talloc_free(call);
    123                         return;
    124                 }
    125 
    126                 DLIST_REMOVE(call->replies, call->replies);
    127         }
    128 
    129         packet_send_callback(conn->packet, blob,
    130                              call->send_callback, call->send_private);
    131         talloc_free(call);
    132         return;
    133 }
    134 
    135 /*
    136   decode/process data
    137 */
    138 static NTSTATUS ldapsrv_decode(void *private_data, DATA_BLOB blob)
    139 {
    140         NTSTATUS status;
    141         struct ldapsrv_connection *conn = talloc_get_type(private_data,
    142                                                           struct ldapsrv_connection);
    143         struct asn1_data *asn1 = asn1_init(conn);
    144         struct ldap_message *msg = talloc(conn, struct ldap_message);
    145 
    146         if (asn1 == NULL || msg == NULL) {
    147                 return NT_STATUS_NO_MEMORY;
    148         }
    149 
    150         if (!asn1_load(asn1, blob)) {
    151                 talloc_free(msg);
    152                 talloc_free(asn1);
    153                 return NT_STATUS_NO_MEMORY;
    154         }
    155 
    156         status = ldap_decode(asn1, samba_ldap_control_handlers(), msg);
    157         if (!NT_STATUS_IS_OK(status)) {
    158                 asn1_free(asn1);
    159                 return status;
    160         }
    161 
    162         data_blob_free(&blob);
    163         talloc_steal(conn, msg);
    164         asn1_free(asn1);
    165 
    166         ldapsrv_process_message(conn, msg);
    167         return NT_STATUS_OK;
    168 }
    169 
    170 /*
    171  Idle timeout handler
    172 */
    173 static void ldapsrv_conn_idle_timeout(struct tevent_context *ev,
    174                                       struct tevent_timer *te,
    175                                       struct timeval t,
    176                                       void *private_data)
    177 {
    178         struct ldapsrv_connection *conn = talloc_get_type(private_data, struct ldapsrv_connection);
    179 
    180         ldapsrv_terminate_connection(conn, "Timeout. No requests after bind");
     118        TALLOC_FREE(conn->sockets.sasl);
     119        conn->sockets.active = conn->sockets.raw;
     120
     121        subreq = tstream_disconnect_send(conn,
     122                                         conn->connection->event.ctx,
     123                                         conn->sockets.active);
     124        if (subreq == NULL) {
     125                TALLOC_FREE(conn->sockets.raw);
     126                stream_terminate_connection(conn->connection,
     127                                            conn->limits.reason);
     128                return;
     129        }
     130        tevent_req_set_endtime(subreq,
     131                               conn->connection->event.ctx,
     132                               conn->limits.endtime);
     133        tevent_req_set_callback(subreq, ldapsrv_terminate_connection_done, conn);
    181134}
    182135
     
    186139void ldapsrv_recv(struct stream_connection *c, uint16_t flags)
    187140{
    188         struct ldapsrv_connection *conn =
    189                 talloc_get_type(c->private_data, struct ldapsrv_connection);
    190 
    191         if (conn->limits.ite) { /* clean initial timeout if any */
    192                 talloc_free(conn->limits.ite);
    193                 conn->limits.ite = NULL;
    194         }
    195 
    196         if (conn->limits.te) { /* clean idle timeout if any */
    197                 talloc_free(conn->limits.te);
    198                 conn->limits.te = NULL;
    199         }
    200 
    201         packet_recv(conn->packet);
    202 
    203         /* set idle timeout */
    204         conn->limits.te = event_add_timed(c->event.ctx, conn,
    205                                            timeval_current_ofs(conn->limits.conn_idle_time, 0),
    206                                            ldapsrv_conn_idle_timeout, conn);
     141        smb_panic(__location__);
    207142}
    208143
     
    212147static void ldapsrv_send(struct stream_connection *c, uint16_t flags)
    213148{
    214         struct ldapsrv_connection *conn =
    215                 talloc_get_type(c->private_data, struct ldapsrv_connection);
    216 
    217         packet_queue_run(conn->packet);
    218 }
    219 
    220 static void ldapsrv_conn_init_timeout(struct tevent_context *ev,
    221                                       struct tevent_timer *te,
    222                                       struct timeval t,
    223                                       void *private_data)
    224 {
    225         struct ldapsrv_connection *conn = talloc_get_type(private_data, struct ldapsrv_connection);
    226 
    227         ldapsrv_terminate_connection(conn, "Timeout. No requests after initial connection");
     149        smb_panic(__location__);
    228150}
    229151
     
    238160        struct ldb_dn *conf_dn;
    239161        struct ldb_dn *policy_dn;
    240         int i,ret;
     162        unsigned int i;
     163        int ret;
    241164
    242165        /* set defaults limits in case of failure */
     
    253176
    254177        basedn = ldb_dn_new(tmp_ctx, conn->ldb, NULL);
    255         if ( ! ldb_dn_validate(basedn)) {
     178        if (basedn == NULL) {
    256179                goto failed;
    257180        }
     
    324247        return -1;
    325248}
     249
     250static struct tevent_req *ldapsrv_process_call_send(TALLOC_CTX *mem_ctx,
     251                                                    struct tevent_context *ev,
     252                                                    struct tevent_queue *call_queue,
     253                                                    struct ldapsrv_call *call);
     254static NTSTATUS ldapsrv_process_call_recv(struct tevent_req *req);
     255
     256static bool ldapsrv_call_read_next(struct ldapsrv_connection *conn);
     257static void ldapsrv_accept_tls_done(struct tevent_req *subreq);
    326258
    327259/*
     
    330262*/
    331263static void ldapsrv_accept(struct stream_connection *c,
    332                            struct auth_session_info *session_info)
     264                           struct auth_session_info *session_info,
     265                           bool is_privileged)
    333266{
    334267        struct ldapsrv_service *ldapsrv_service =
     
    339272        NTSTATUS status;
    340273        int port;
     274        int ret;
     275        struct tevent_req *subreq;
     276        struct timeval endtime;
    341277
    342278        conn = talloc_zero(c, struct ldapsrv_connection);
     
    345281                return;
    346282        }
    347 
    348         conn->packet      = NULL;
     283        conn->is_privileged = is_privileged;
     284
     285        conn->sockets.send_queue = tevent_queue_create(conn, "ldapsev send queue");
     286        if (conn->sockets.send_queue == NULL) {
     287                stream_terminate_connection(c,
     288                                            "ldapsrv_accept: tevent_queue_create failed");
     289                return;
     290        }
     291
     292        TALLOC_FREE(c->event.fde);
     293
     294        ret = tstream_bsd_existing_socket(conn,
     295                                          socket_get_fd(c->socket),
     296                                          &conn->sockets.raw);
     297        if (ret == -1) {
     298                stream_terminate_connection(c,
     299                                            "ldapsrv_accept: out of memory");
     300                return;
     301        }
     302        socket_set_flags(c->socket, SOCKET_FLAG_NOCLOSE);
     303
    349304        conn->connection  = c;
    350305        conn->service     = ldapsrv_service;
    351         conn->sockets.raw = c->socket;
    352306        conn->lp_ctx      = ldapsrv_service->task->lp_ctx;
    353307
     
    361315        port = socket_address->port;
    362316        talloc_free(socket_address);
    363 
    364         if (port == 636) {
    365                 struct socket_context *tls_socket = tls_init_server(ldapsrv_service->tls_params, c->socket,
    366                                                                     c->event.fde, NULL);
    367                 if (!tls_socket) {
    368                         ldapsrv_terminate_connection(conn, "ldapsrv_accept: tls_init_server() failed");
    369                         return;
    370                 }
    371                 talloc_steal(c, tls_socket);
    372                 c->socket = tls_socket;
    373                 conn->sockets.tls = tls_socket;
    374 
    375         } else if (port == 3268) /* Global catalog */ {
     317        if (port == 3268 || port == 3269) /* Global catalog */ {
    376318                conn->global_catalog = true;
    377319        }
    378         conn->packet = packet_init(conn);
    379         if (conn->packet == NULL) {
    380                 ldapsrv_terminate_connection(conn, "out of memory");
    381                 return;
    382         }
    383 
    384         packet_set_private(conn->packet, conn);
    385         packet_set_socket(conn->packet, c->socket);
    386         packet_set_callback(conn->packet, ldapsrv_decode);
    387         packet_set_full_request(conn->packet, ldap_full_packet);
    388         packet_set_error_handler(conn->packet, ldapsrv_error_handler);
    389         packet_set_event_context(conn->packet, c->event.ctx);
    390         packet_set_fde(conn->packet, c->event.fde);
    391         packet_set_serialise(conn->packet);
    392 
    393         if (conn->sockets.tls) {
    394                 packet_set_unreliable_select(conn->packet);
    395         }
    396 
    397         /* Ensure we don't get packets until the database is ready below */
    398         packet_recv_disable(conn->packet);
    399320
    400321        server_credentials = cli_credentials_init(conn);
     
    412333        conn->server_credentials = server_credentials;
    413334
    414         conn->session_info = talloc_move(conn, &session_info);
     335        conn->session_info = session_info;
    415336
    416337        if (!NT_STATUS_IS_OK(ldapsrv_backend_Init(conn))) {
     
    425346        irpc_add_name(c->msg_ctx, "ldap_server");
    426347
    427         /* set connections limits */
    428         conn->limits.ite = event_add_timed(c->event.ctx, conn,
    429                                            timeval_current_ofs(conn->limits.initial_timeout, 0),
    430                                            ldapsrv_conn_init_timeout, conn);
    431 
    432         packet_recv_enable(conn->packet);
    433 
     348        conn->sockets.active = conn->sockets.raw;
     349
     350        if (port != 636 && port != 3269) {
     351                ldapsrv_call_read_next(conn);
     352                return;
     353        }
     354
     355        endtime = timeval_current_ofs(conn->limits.conn_idle_time, 0);
     356
     357        subreq = tstream_tls_accept_send(conn,
     358                                         conn->connection->event.ctx,
     359                                         conn->sockets.raw,
     360                                         conn->service->tls_params);
     361        if (subreq == NULL) {
     362                ldapsrv_terminate_connection(conn, "ldapsrv_accept: "
     363                                "no memory for tstream_tls_accept_send");
     364                return;
     365        }
     366        tevent_req_set_endtime(subreq,
     367                               conn->connection->event.ctx,
     368                               endtime);
     369        tevent_req_set_callback(subreq, ldapsrv_accept_tls_done, conn);
     370}
     371
     372static void ldapsrv_accept_tls_done(struct tevent_req *subreq)
     373{
     374        struct ldapsrv_connection *conn =
     375                tevent_req_callback_data(subreq,
     376                struct ldapsrv_connection);
     377        int ret;
     378        int sys_errno;
     379
     380        ret = tstream_tls_accept_recv(subreq, &sys_errno,
     381                                      conn, &conn->sockets.tls);
     382        TALLOC_FREE(subreq);
     383        if (ret == -1) {
     384                const char *reason;
     385
     386                reason = talloc_asprintf(conn, "ldapsrv_accept_tls_loop: "
     387                                         "tstream_tls_accept_recv() - %d:%s",
     388                                         sys_errno, strerror(sys_errno));
     389                if (!reason) {
     390                        reason = "ldapsrv_accept_tls_loop: "
     391                                 "tstream_tls_accept_recv() - failed";
     392                }
     393
     394                ldapsrv_terminate_connection(conn, reason);
     395                return;
     396        }
     397
     398        conn->sockets.active = conn->sockets.tls;
     399        ldapsrv_call_read_next(conn);
     400}
     401
     402static void ldapsrv_call_read_done(struct tevent_req *subreq);
     403
     404static bool ldapsrv_call_read_next(struct ldapsrv_connection *conn)
     405{
     406        struct tevent_req *subreq;
     407
     408        if (timeval_is_zero(&conn->limits.endtime)) {
     409                conn->limits.endtime =
     410                        timeval_current_ofs(conn->limits.initial_timeout, 0);
     411        } else {
     412                conn->limits.endtime =
     413                        timeval_current_ofs(conn->limits.conn_idle_time, 0);
     414        }
     415
     416        /*
     417         * The minimun size of a LDAP pdu is 7 bytes
     418         *
     419         * dumpasn1 -hh ldap-unbind-min.dat
     420         *
     421         *     <30 05 02 01 09 42 00>
     422         *    0    5: SEQUENCE {
     423         *     <02 01 09>
     424         *    2    1:   INTEGER 9
     425         *     <42 00>
     426         *    5    0:   [APPLICATION 2]
     427         *          :     Error: Object has zero length.
     428         *          :   }
     429         *
     430         * dumpasn1 -hh ldap-unbind-windows.dat
     431         *
     432         *     <30 84 00 00 00 05 02 01 09 42 00>
     433         *    0    5: SEQUENCE {
     434         *     <02 01 09>
     435         *    6    1:   INTEGER 9
     436         *     <42 00>
     437         *    9    0:   [APPLICATION 2]
     438         *          :     Error: Object has zero length.
     439         *          :   }
     440         *
     441         * This means using an initial read size
     442         * of 7 is ok.
     443         */
     444        subreq = tstream_read_pdu_blob_send(conn,
     445                                            conn->connection->event.ctx,
     446                                            conn->sockets.active,
     447                                            7, /* initial_read_size */
     448                                            ldap_full_packet,
     449                                            conn);
     450        if (subreq == NULL) {
     451                ldapsrv_terminate_connection(conn, "ldapsrv_call_read_next: "
     452                                "no memory for tstream_read_pdu_blob_send");
     453                return false;
     454        }
     455        tevent_req_set_endtime(subreq,
     456                               conn->connection->event.ctx,
     457                               conn->limits.endtime);
     458        tevent_req_set_callback(subreq, ldapsrv_call_read_done, conn);
     459        return true;
     460}
     461
     462static void ldapsrv_call_process_done(struct tevent_req *subreq);
     463
     464static void ldapsrv_call_read_done(struct tevent_req *subreq)
     465{
     466        struct ldapsrv_connection *conn =
     467                tevent_req_callback_data(subreq,
     468                struct ldapsrv_connection);
     469        NTSTATUS status;
     470        struct ldapsrv_call *call;
     471        struct asn1_data *asn1;
     472        DATA_BLOB blob;
     473
     474        call = talloc_zero(conn, struct ldapsrv_call);
     475        if (!call) {
     476                ldapsrv_terminate_connection(conn, "no memory");
     477                return;
     478        }
     479
     480        call->conn = conn;
     481
     482        status = tstream_read_pdu_blob_recv(subreq,
     483                                            call,
     484                                            &blob);
     485        TALLOC_FREE(subreq);
     486        if (!NT_STATUS_IS_OK(status)) {
     487                const char *reason;
     488
     489                reason = talloc_asprintf(call, "ldapsrv_call_loop: "
     490                                         "tstream_read_pdu_blob_recv() - %s",
     491                                         nt_errstr(status));
     492                if (!reason) {
     493                        reason = nt_errstr(status);
     494                }
     495
     496                ldapsrv_terminate_connection(conn, reason);
     497                return;
     498        }
     499
     500        asn1 = asn1_init(call);
     501        if (asn1 == NULL) {
     502                ldapsrv_terminate_connection(conn, "no memory");
     503                return;
     504        }
     505
     506        call->request = talloc(call, struct ldap_message);
     507        if (call->request == NULL) {
     508                ldapsrv_terminate_connection(conn, "no memory");
     509                return;
     510        }
     511
     512        if (!asn1_load(asn1, blob)) {
     513                ldapsrv_terminate_connection(conn, "asn1_load failed");
     514                return;
     515        }
     516
     517        status = ldap_decode(asn1, samba_ldap_control_handlers(),
     518                             call->request);
     519        if (!NT_STATUS_IS_OK(status)) {
     520                ldapsrv_terminate_connection(conn, nt_errstr(status));
     521                return;
     522        }
     523
     524        data_blob_free(&blob);
     525
     526
     527        /* queue the call in the global queue */
     528        subreq = ldapsrv_process_call_send(call,
     529                                           conn->connection->event.ctx,
     530                                           conn->service->call_queue,
     531                                           call);
     532        if (subreq == NULL) {
     533                ldapsrv_terminate_connection(conn, "ldapsrv_process_call_send failed");
     534                return;
     535        }
     536        tevent_req_set_callback(subreq, ldapsrv_call_process_done, call);
     537        conn->active_call = subreq;
     538}
     539
     540static void ldapsrv_call_writev_done(struct tevent_req *subreq);
     541
     542static void ldapsrv_call_process_done(struct tevent_req *subreq)
     543{
     544        struct ldapsrv_call *call =
     545                tevent_req_callback_data(subreq,
     546                struct ldapsrv_call);
     547        struct ldapsrv_connection *conn = call->conn;
     548        NTSTATUS status;
     549        DATA_BLOB blob = data_blob_null;
     550
     551        conn->active_call = NULL;
     552
     553        status = ldapsrv_process_call_recv(subreq);
     554        TALLOC_FREE(subreq);
     555        if (!NT_STATUS_IS_OK(status)) {
     556                ldapsrv_terminate_connection(conn, nt_errstr(status));
     557                return;
     558        }
     559
     560        /* build all the replies into a single blob */
     561        while (call->replies) {
     562                DATA_BLOB b;
     563                bool ret;
     564
     565                if (!ldap_encode(call->replies->msg, samba_ldap_control_handlers(), &b, call)) {
     566                        DEBUG(0,("Failed to encode ldap reply of type %d\n",
     567                                 call->replies->msg->type));
     568                        ldapsrv_terminate_connection(conn, "ldap_encode failed");
     569                        return;
     570                }
     571
     572                ret = data_blob_append(call, &blob, b.data, b.length);
     573                data_blob_free(&b);
     574
     575                talloc_set_name_const(blob.data, "Outgoing, encoded LDAP packet");
     576
     577                if (!ret) {
     578                        ldapsrv_terminate_connection(conn, "data_blob_append failed");
     579                        return;
     580                }
     581
     582                DLIST_REMOVE(call->replies, call->replies);
     583        }
     584
     585        if (blob.length == 0) {
     586                TALLOC_FREE(call);
     587
     588                ldapsrv_call_read_next(conn);
     589                return;
     590        }
     591
     592        call->out_iov.iov_base = blob.data;
     593        call->out_iov.iov_len = blob.length;
     594
     595        subreq = tstream_writev_queue_send(call,
     596                                           conn->connection->event.ctx,
     597                                           conn->sockets.active,
     598                                           conn->sockets.send_queue,
     599                                           &call->out_iov, 1);
     600        if (subreq == NULL) {
     601                ldapsrv_terminate_connection(conn, "stream_writev_queue_send failed");
     602                return;
     603        }
     604        tevent_req_set_callback(subreq, ldapsrv_call_writev_done, call);
     605}
     606
     607static void ldapsrv_call_postprocess_done(struct tevent_req *subreq);
     608
     609static void ldapsrv_call_writev_done(struct tevent_req *subreq)
     610{
     611        struct ldapsrv_call *call =
     612                tevent_req_callback_data(subreq,
     613                struct ldapsrv_call);
     614        struct ldapsrv_connection *conn = call->conn;
     615        int sys_errno;
     616        int rc;
     617
     618        rc = tstream_writev_queue_recv(subreq, &sys_errno);
     619        TALLOC_FREE(subreq);
     620        if (rc == -1) {
     621                const char *reason;
     622
     623                reason = talloc_asprintf(call, "ldapsrv_call_writev_done: "
     624                                         "tstream_writev_queue_recv() - %d:%s",
     625                                         sys_errno, strerror(sys_errno));
     626                if (reason == NULL) {
     627                        reason = "ldapsrv_call_writev_done: "
     628                                 "tstream_writev_queue_recv() failed";
     629                }
     630
     631                ldapsrv_terminate_connection(conn, reason);
     632                return;
     633        }
     634
     635        if (call->postprocess_send) {
     636                subreq = call->postprocess_send(call,
     637                                                conn->connection->event.ctx,
     638                                                call->postprocess_private);
     639                if (subreq == NULL) {
     640                        ldapsrv_terminate_connection(conn, "ldapsrv_call_writev_done: "
     641                                        "call->postprocess_send - no memory");
     642                        return;
     643                }
     644                tevent_req_set_callback(subreq,
     645                                        ldapsrv_call_postprocess_done,
     646                                        call);
     647                return;
     648        }
     649
     650        TALLOC_FREE(call);
     651
     652        ldapsrv_call_read_next(conn);
     653}
     654
     655static void ldapsrv_call_postprocess_done(struct tevent_req *subreq)
     656{
     657        struct ldapsrv_call *call =
     658                tevent_req_callback_data(subreq,
     659                struct ldapsrv_call);
     660        struct ldapsrv_connection *conn = call->conn;
     661        NTSTATUS status;
     662
     663        status = call->postprocess_recv(subreq);
     664        TALLOC_FREE(subreq);
     665        if (!NT_STATUS_IS_OK(status)) {
     666                const char *reason;
     667
     668                reason = talloc_asprintf(call, "ldapsrv_call_postprocess_done: "
     669                                         "call->postprocess_recv() - %s",
     670                                         nt_errstr(status));
     671                if (reason == NULL) {
     672                        reason = nt_errstr(status);
     673                }
     674
     675                ldapsrv_terminate_connection(conn, reason);
     676                return;
     677        }
     678
     679        TALLOC_FREE(call);
     680
     681        ldapsrv_call_read_next(conn);
     682}
     683
     684struct ldapsrv_process_call_state {
     685        struct ldapsrv_call *call;
     686};
     687
     688static void ldapsrv_process_call_trigger(struct tevent_req *req,
     689                                         void *private_data);
     690
     691static struct tevent_req *ldapsrv_process_call_send(TALLOC_CTX *mem_ctx,
     692                                                    struct tevent_context *ev,
     693                                                    struct tevent_queue *call_queue,
     694                                                    struct ldapsrv_call *call)
     695{
     696        struct tevent_req *req;
     697        struct ldapsrv_process_call_state *state;
     698        bool ok;
     699
     700        req = tevent_req_create(mem_ctx, &state,
     701                                struct ldapsrv_process_call_state);
     702        if (req == NULL) {
     703                return req;
     704        }
     705
     706        state->call = call;
     707
     708        ok = tevent_queue_add(call_queue, ev, req,
     709                              ldapsrv_process_call_trigger, NULL);
     710        if (!ok) {
     711                tevent_req_nomem(NULL, req);
     712                return tevent_req_post(req, ev);
     713        }
     714
     715        return req;
     716}
     717
     718static void ldapsrv_process_call_trigger(struct tevent_req *req,
     719                                         void *private_data)
     720{
     721        struct ldapsrv_process_call_state *state =
     722                tevent_req_data(req,
     723                struct ldapsrv_process_call_state);
     724        NTSTATUS status;
     725
     726        /* make the call */
     727        status = ldapsrv_do_call(state->call);
     728        if (!NT_STATUS_IS_OK(status)) {
     729                tevent_req_nterror(req, status);
     730                return;
     731        }
     732
     733        tevent_req_done(req);
     734}
     735
     736static NTSTATUS ldapsrv_process_call_recv(struct tevent_req *req)
     737{
     738        NTSTATUS status;
     739
     740        if (tevent_req_is_nterror(req, &status)) {
     741                tevent_req_received(req);
     742                return status;
     743        }
     744
     745        tevent_req_received(req);
     746        return NT_STATUS_OK;
    434747}
    435748
     
    442755
    443756        status = auth_anonymous_session_info(
    444                 c, c->event.ctx, ldapsrv_service->task->lp_ctx, &session_info);
     757                c, ldapsrv_service->task->lp_ctx, &session_info);
    445758        if (!NT_STATUS_IS_OK(status)) {
    446759                stream_terminate_connection(c, "failed to setup anonymous "
     
    448761                return;
    449762        }
    450         ldapsrv_accept(c, session_info);
     763        ldapsrv_accept(c, session_info, false);
    451764}
    452765
     
    469782                c->private_data, struct ldapsrv_service);
    470783        struct auth_session_info *session_info;
    471         NTSTATUS status;
    472 
    473         status = auth_system_session_info(
    474                 c, ldapsrv_service->task->lp_ctx, &session_info);
    475         if (!NT_STATUS_IS_OK(status)) {
     784
     785        session_info = system_session(ldapsrv_service->task->lp_ctx);
     786        if (!session_info) {
    476787                stream_terminate_connection(c, "failed to setup system "
    477788                                            "session info");
    478789                return;
    479790        }
    480         ldapsrv_accept(c, session_info);
     791        ldapsrv_accept(c, session_info, true);
    481792}
    482793
     
    489800
    490801#endif
     802
     803
    491804/*
    492805  add a socket address to the list of events, one event per port
    493806*/
    494 static NTSTATUS add_socket(struct tevent_context *event_context,
    495                            struct loadparm_context *lp_ctx, 
     807static NTSTATUS add_socket(struct task_server *task,
     808                           struct loadparm_context *lp_ctx,
    496809                           const struct model_ops *model_ops,
    497810                           const char *address, struct ldapsrv_service *ldap_service)
     
    501814        struct ldb_context *ldb;
    502815
    503         status = stream_setup_socket(event_context, lp_ctx,
     816        status = stream_setup_socket(task, task->event_ctx, lp_ctx,
    504817                                     model_ops, &ldap_stream_nonpriv_ops,
    505818                                     "ipv4", address, &port,
    506                                      lp_socket_options(lp_ctx),
     819                                     lpcfg_socket_options(lp_ctx),
    507820                                     ldap_service);
    508821        if (!NT_STATUS_IS_OK(status)) {
    509822                DEBUG(0,("ldapsrv failed to bind to %s:%u - %s\n",
    510823                         address, port, nt_errstr(status)));
    511         }
    512 
    513         if (tls_support(ldap_service->tls_params)) {
     824                return status;
     825        }
     826
     827        if (tstream_tls_params_enabled(ldap_service->tls_params)) {
    514828                /* add ldaps server */
    515829                port = 636;
    516                 status = stream_setup_socket(event_context, lp_ctx,
     830                status = stream_setup_socket(task, task->event_ctx, lp_ctx,
    517831                                             model_ops,
    518832                                             &ldap_stream_nonpriv_ops,
    519833                                             "ipv4", address, &port,
    520                                              lp_socket_options(lp_ctx),
     834                                             lpcfg_socket_options(lp_ctx),
    521835                                             ldap_service);
    522836                if (!NT_STATUS_IS_OK(status)) {
    523837                        DEBUG(0,("ldapsrv failed to bind to %s:%u - %s\n",
    524838                                 address, port, nt_errstr(status)));
     839                        return status;
    525840                }
    526841        }
     
    528843        /* Load LDAP database, but only to read our settings */
    529844        ldb = samdb_connect(ldap_service, ldap_service->task->event_ctx,
    530                             lp_ctx, system_session(ldap_service, lp_ctx));
     845                            lp_ctx, system_session(lp_ctx), 0);
    531846        if (!ldb) {
    532847                return NT_STATUS_INTERNAL_DB_CORRUPTION;
     
    535850        if (samdb_is_gc(ldb)) {
    536851                port = 3268;
    537                 status = stream_setup_socket(event_context, lp_ctx,
     852                status = stream_setup_socket(task, task->event_ctx, lp_ctx,
    538853                                             model_ops,
    539854                                             &ldap_stream_nonpriv_ops,
    540855                                             "ipv4", address, &port,
    541                                              lp_socket_options(lp_ctx),
     856                                             lpcfg_socket_options(lp_ctx),
    542857                                             ldap_service);
    543858                if (!NT_STATUS_IS_OK(status)) {
    544859                        DEBUG(0,("ldapsrv failed to bind to %s:%u - %s\n",
    545860                                 address, port, nt_errstr(status)));
    546                 }
    547         }
    548 
    549         /* And once we are bound, free the tempoary ldb, it will
     861                        return status;
     862                }
     863                if (tstream_tls_params_enabled(ldap_service->tls_params)) {
     864                        /* add ldaps server for the global catalog */
     865                        port = 3269;
     866                        status = stream_setup_socket(task, task->event_ctx, lp_ctx,
     867                                                     model_ops,
     868                                                     &ldap_stream_nonpriv_ops,
     869                                                     "ipv4", address, &port,
     870                                                     lpcfg_socket_options(lp_ctx),
     871                                                     ldap_service);
     872                        if (!NT_STATUS_IS_OK(status)) {
     873                                DEBUG(0,("ldapsrv failed to bind to %s:%u - %s\n",
     874                                         address, port, nt_errstr(status)));
     875                                return status;
     876                        }
     877                }
     878        }
     879
     880        /* And once we are bound, free the temporary ldb, it will
    550881         * connect again on each incoming LDAP connection */
    551         talloc_free(ldb);
    552 
    553         return status;
     882        talloc_unlink(ldap_service, ldb);
     883
     884        return NT_STATUS_OK;
    554885}
    555886
     
    563894        char *priv_dir;
    564895#endif
     896        const char *dns_host_name;
    565897        struct ldapsrv_service *ldap_service;
    566898        NTSTATUS status;
    567899        const struct model_ops *model_ops;
    568900
    569         switch (lp_server_role(task->lp_ctx)) {
     901        switch (lpcfg_server_role(task->lp_ctx)) {
    570902        case ROLE_STANDALONE:
    571903                task_server_terminate(task, "ldap_server: no LDAP server required in standalone configuration",
     
    584916
    585917        /* run the ldap server as a single process */
    586         model_ops = process_model_startup(task->event_ctx, "single");
     918        model_ops = process_model_startup("single");
    587919        if (!model_ops) goto failed;
    588920
     
    592924        ldap_service->task = task;
    593925
    594         ldap_service->tls_params = tls_initialise(ldap_service, task->lp_ctx);
    595         if (ldap_service->tls_params == NULL) goto failed;
    596 
    597         if (lp_interfaces(task->lp_ctx) && lp_bind_interfaces_only(task->lp_ctx)) {
     926        dns_host_name = talloc_asprintf(ldap_service, "%s.%s",
     927                                        lpcfg_netbios_name(task->lp_ctx),
     928                                        lpcfg_dnsdomain(task->lp_ctx));
     929        if (dns_host_name == NULL) goto failed;
     930
     931        status = tstream_tls_params_server(ldap_service,
     932                                           dns_host_name,
     933                                           lpcfg_tls_enabled(task->lp_ctx),
     934                                           lpcfg_tls_keyfile(ldap_service, task->lp_ctx),
     935                                           lpcfg_tls_certfile(ldap_service, task->lp_ctx),
     936                                           lpcfg_tls_cafile(ldap_service, task->lp_ctx),
     937                                           lpcfg_tls_crlfile(ldap_service, task->lp_ctx),
     938                                           lpcfg_tls_dhpfile(ldap_service, task->lp_ctx),
     939                                           &ldap_service->tls_params);
     940        if (!NT_STATUS_IS_OK(status)) {
     941                DEBUG(0,("ldapsrv failed tstream_tls_patams_server - %s\n",
     942                         nt_errstr(status)));
     943                goto failed;
     944        }
     945
     946        ldap_service->call_queue = tevent_queue_create(ldap_service, "ldapsrv_call_queue");
     947        if (ldap_service->call_queue == NULL) goto failed;
     948
     949        if (lpcfg_interfaces(task->lp_ctx) && lpcfg_bind_interfaces_only(task->lp_ctx)) {
    598950                struct interface *ifaces;
    599951                int num_interfaces;
    600952                int i;
    601953
    602                 load_interfaces(task, lp_interfaces(task->lp_ctx), &ifaces);
     954                load_interfaces(task, lpcfg_interfaces(task->lp_ctx), &ifaces);
    603955                num_interfaces = iface_count(ifaces);
    604956
     
    609961                for(i = 0; i < num_interfaces; i++) {
    610962                        const char *address = iface_n_ip(ifaces, i);
    611                         status = add_socket(task->event_ctx, task->lp_ctx, model_ops, address, ldap_service);
     963                        status = add_socket(task, task->lp_ctx, model_ops, address, ldap_service);
    612964                        if (!NT_STATUS_IS_OK(status)) goto failed;
    613965                }
    614966        } else {
    615                 status = add_socket(task->event_ctx, task->lp_ctx, model_ops,
    616                                     lp_socket_address(task->lp_ctx), ldap_service);
     967                status = add_socket(task, task->lp_ctx, model_ops,
     968                                    lpcfg_socket_address(task->lp_ctx), ldap_service);
    617969                if (!NT_STATUS_IS_OK(status)) goto failed;
    618970        }
     
    623975        }
    624976
    625         status = stream_setup_socket(task->event_ctx, task->lp_ctx,
     977        status = stream_setup_socket(task, task->event_ctx, task->lp_ctx,
    626978                                     model_ops, &ldap_stream_nonpriv_ops,
    627979                                     "unix", ldapi_path, NULL,
    628                                      lp_socket_options(task->lp_ctx),
     980                                     lpcfg_socket_options(task->lp_ctx),
    629981                                     ldap_service);
    630982        talloc_free(ldapi_path);
     
    6541006        }
    6551007
    656         status = stream_setup_socket(task->event_ctx, task->lp_ctx,
     1008        status = stream_setup_socket(task, task->event_ctx, task->lp_ctx,
    6571009                                     model_ops, &ldap_stream_priv_ops,
    6581010                                     "unix", ldapi_path, NULL,
    659                                      lp_socket_options(task->lp_ctx),
     1011                                     lpcfg_socket_options(task->lp_ctx),
    6601012                                     ldap_service);
    6611013        talloc_free(ldapi_path);
  • vendor/current/source4/ldap_server/ldap_server.h

    r414 r740  
    1919*/
    2020
    21 #include "libcli/ldap/ldap.h"
     21#include "libcli/ldap/libcli_ldap.h"
    2222#include "lib/socket/socket.h"
    2323#include "lib/stream/packet.h"
     24#include "system/network.h"
    2425
    2526struct ldapsrv_connection {
     
    3334
    3435        struct {
    35                 struct socket_context *raw;
    36                 struct socket_context *tls;
    37                 struct socket_context *sasl;
     36                struct tevent_queue *send_queue;
     37                struct tstream_context *raw;
     38                struct tstream_context *tls;
     39                struct tstream_context *sasl;
     40                struct tstream_context *active;
    3841        } sockets;
    3942
    4043        bool global_catalog;
    41 
    42         struct packet_context *packet;
     44        bool is_privileged;
    4345
    4446        struct {
     
    4749                int max_page_size;
    4850                int search_timeout;
    49                
    50                 struct tevent_timer *ite;
    51                 struct tevent_timer *te;
     51                struct timeval endtime;
     52                const char *reason;
    5253        } limits;
     54
     55        struct tevent_req *active_call;
    5356};
    5457
     
    6063                struct ldap_message *msg;
    6164        } *replies;
    62         packet_send_callback_fn_t send_callback;
    63         void *send_private;
     65        struct iovec out_iov;
     66
     67        struct tevent_req *(*postprocess_send)(TALLOC_CTX *mem_ctx,
     68                                               struct tevent_context *ev,
     69                                               void *private_data);
     70        NTSTATUS (*postprocess_recv)(struct tevent_req *req);
     71        void *postprocess_private;
    6472};
    6573
    6674struct ldapsrv_service {
    67         struct tls_params *tls_params;
     75        struct tstream_tls_params *tls_params;
    6876        struct task_server *task;
     77        struct tevent_queue *call_queue;
    6978};
    7079
Note: See TracChangeset for help on using the changeset viewer.