LCOV - code coverage report
Current view: top level - source4/libcli/ldap - ldap_bind.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 183 259 70.7 %
Date: 2024-04-21 15:09:00 Functions: 4 5 80.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    LDAP bind calls
       5             :    
       6             :    Copyright (C) Andrew Tridgell  2005
       7             :    Copyright (C) Volker Lendecke  2004
       8             :     
       9             :    This program is free software; you can redistribute it and/or modify
      10             :    it under the terms of the GNU General Public License as published by
      11             :    the Free Software Foundation; either version 3 of the License, or
      12             :    (at your option) any later version.
      13             :    
      14             :    This program is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU General Public License for more details.
      18             :    
      19             :    You should have received a copy of the GNU General Public License
      20             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      21             :    
      22             : */
      23             : 
      24             : #include "includes.h"
      25             : #include "libcli/ldap/libcli_ldap.h"
      26             : #include "libcli/ldap/ldap_proto.h"
      27             : #include "libcli/ldap/ldap_client.h"
      28             : #include "lib/tls/tls.h"
      29             : #include "auth/gensec/gensec.h"
      30             : #include "auth/gensec/gensec_internal.h" /* TODO: remove this */
      31             : #include "source4/auth/gensec/gensec_tstream.h"
      32             : #include "auth/credentials/credentials.h"
      33             : #include "lib/stream/packet.h"
      34             : #include "param/param.h"
      35             : #include "param/loadparm.h"
      36             : #include "librpc/gen_ndr/ads.h"
      37             : 
      38             : struct ldap_simple_creds {
      39             :         const char *dn;
      40             :         const char *pw;
      41             : };
      42             : 
      43           0 : _PUBLIC_ NTSTATUS ldap_rebind(struct ldap_connection *conn)
      44             : {
      45           0 :         NTSTATUS status;
      46           0 :         struct ldap_simple_creds *creds;
      47             : 
      48           0 :         switch (conn->bind.type) {
      49           0 :         case LDAP_BIND_SASL:
      50           0 :                 status = ldap_bind_sasl(conn, (struct cli_credentials *)conn->bind.creds,
      51             :                                         conn->lp_ctx);
      52           0 :                 break;
      53             :                 
      54           0 :         case LDAP_BIND_SIMPLE:
      55           0 :                 creds = (struct ldap_simple_creds *)conn->bind.creds;
      56             : 
      57           0 :                 if (creds == NULL) {
      58           0 :                         return NT_STATUS_UNSUCCESSFUL;
      59             :                 }
      60             : 
      61           0 :                 status = ldap_bind_simple(conn, creds->dn, creds->pw);
      62           0 :                 break;
      63             : 
      64           0 :         default:
      65           0 :                 return NT_STATUS_UNSUCCESSFUL;
      66             :         }
      67             : 
      68           0 :         return status;
      69             : }
      70             : 
      71             : 
      72         444 : static struct ldap_message *new_ldap_simple_bind_msg(struct ldap_connection *conn, 
      73             :                                                      const char *dn, const char *pw)
      74             : {
      75           0 :         struct ldap_message *res;
      76             : 
      77         444 :         res = new_ldap_message(conn);
      78         444 :         if (!res) {
      79           0 :                 return NULL;
      80             :         }
      81             : 
      82         444 :         res->type = LDAP_TAG_BindRequest;
      83         444 :         res->r.BindRequest.version = 3;
      84         444 :         res->r.BindRequest.dn = talloc_strdup(res, dn);
      85         444 :         res->r.BindRequest.mechanism = LDAP_AUTH_MECH_SIMPLE;
      86         444 :         res->r.BindRequest.creds.password = talloc_strdup(res, pw);
      87         444 :         res->controls = NULL;
      88             : 
      89         444 :         return res;
      90             : }
      91             : 
      92             : 
      93             : /*
      94             :   perform a simple username/password bind
      95             : */
      96         444 : _PUBLIC_ NTSTATUS ldap_bind_simple(struct ldap_connection *conn, 
      97             :                           const char *userdn, const char *password)
      98             : {
      99           0 :         struct ldap_request *req;
     100           0 :         struct ldap_message *msg;
     101           0 :         const char *dn, *pw;
     102           0 :         NTSTATUS status;
     103             : 
     104         444 :         if (conn == NULL) {
     105           0 :                 return NT_STATUS_INVALID_CONNECTION;
     106             :         }
     107             : 
     108         444 :         if (userdn) {
     109         443 :                 dn = userdn;
     110             :         } else {
     111           1 :                 if (conn->auth_dn) {
     112           0 :                         dn = conn->auth_dn;
     113             :                 } else {
     114           1 :                         dn = "";
     115             :                 }
     116             :         }
     117             : 
     118         444 :         if (password) {
     119         443 :                 pw = password;
     120             :         } else {
     121           1 :                 if (conn->simple_pw) {
     122           0 :                         pw = conn->simple_pw;
     123             :                 } else {
     124           1 :                         pw = "";
     125             :                 }
     126             :         }
     127             : 
     128         444 :         msg = new_ldap_simple_bind_msg(conn, dn, pw);
     129         444 :         NT_STATUS_HAVE_NO_MEMORY(msg);
     130             : 
     131             :         /* send the request */
     132         444 :         req = ldap_request_send(conn, msg);
     133         444 :         talloc_free(msg);
     134         444 :         NT_STATUS_HAVE_NO_MEMORY(req);
     135             : 
     136             :         /* wait for replies */
     137         444 :         status = ldap_request_wait(req);
     138         444 :         if (!NT_STATUS_IS_OK(status)) {
     139           0 :                 talloc_free(req);
     140           0 :                 return status;
     141             :         }
     142             : 
     143             :         /* check its a valid reply */
     144         444 :         msg = req->replies[0];
     145         444 :         if (msg->type != LDAP_TAG_BindResponse) {
     146           0 :                 talloc_free(req);
     147           0 :                 return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
     148             :         }
     149             : 
     150         444 :         status = ldap_check_response(conn, &msg->r.BindResponse.response);
     151             : 
     152         444 :         talloc_free(req);
     153             : 
     154         444 :         if (NT_STATUS_IS_OK(status)) {
     155         319 :                 struct ldap_simple_creds *creds = talloc(conn, struct ldap_simple_creds);
     156         319 :                 if (creds == NULL) {
     157           0 :                         return NT_STATUS_NO_MEMORY;
     158             :                 }
     159         319 :                 creds->dn = talloc_strdup(creds, dn);
     160         319 :                 creds->pw = talloc_strdup(creds, pw);
     161         319 :                 if (creds->dn == NULL || creds->pw == NULL) {
     162           0 :                         return NT_STATUS_NO_MEMORY;
     163             :                 }
     164         319 :                 conn->bind.type = LDAP_BIND_SIMPLE;
     165         319 :                 conn->bind.creds = creds;
     166             :         }
     167             : 
     168         444 :         return status;
     169             : }
     170             : 
     171             : 
     172       35034 : static struct ldap_message *new_ldap_sasl_bind_msg(struct ldap_connection *conn, 
     173             :                                                    const char *sasl_mechanism, 
     174             :                                                    DATA_BLOB *secblob)
     175             : {
     176         122 :         struct ldap_message *res;
     177             : 
     178       35034 :         res = new_ldap_message(conn);
     179       35034 :         if (!res) {
     180           0 :                 return NULL;
     181             :         }
     182             : 
     183       35034 :         res->type = LDAP_TAG_BindRequest;
     184       35034 :         res->r.BindRequest.version = 3;
     185       35034 :         res->r.BindRequest.dn = "";
     186       35034 :         res->r.BindRequest.mechanism = LDAP_AUTH_MECH_SASL;
     187       35034 :         res->r.BindRequest.creds.SASL.mechanism = talloc_strdup(res, sasl_mechanism);
     188       35034 :         if (secblob) {
     189       35034 :                 res->r.BindRequest.creds.SASL.secblob = talloc(res, DATA_BLOB);
     190       35034 :                 if (!res->r.BindRequest.creds.SASL.secblob) {
     191           0 :                         talloc_free(res);
     192           0 :                         return NULL;
     193             :                 }
     194       35034 :                 *res->r.BindRequest.creds.SASL.secblob = *secblob;
     195             :         } else {
     196           0 :                 res->r.BindRequest.creds.SASL.secblob = NULL;
     197             :         }
     198       35034 :         res->controls = NULL;
     199             : 
     200       35034 :         return res;
     201             : }
     202             : 
     203             : 
     204             : /*
     205             :   perform a sasl bind using the given credentials
     206             : */
     207       26102 : _PUBLIC_ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn,
     208             :                         struct cli_credentials *creds,
     209             :                         struct loadparm_context *lp_ctx)
     210             : {
     211         122 :         NTSTATUS status;
     212       26102 :         TALLOC_CTX *tmp_ctx = NULL;
     213             : 
     214       26102 :         DATA_BLOB input = data_blob(NULL, 0);
     215       26102 :         DATA_BLOB output = data_blob(NULL, 0);
     216             : 
     217         122 :         struct ldap_message **sasl_mechs_msgs;
     218         122 :         struct ldap_SearchResEntry *search;
     219         122 :         int count, i;
     220       26102 :         bool first = true;
     221       26102 :         int wrap_flags = 0;
     222         122 :         const char **sasl_names;
     223         122 :         uint32_t old_gensec_features;
     224         122 :         static const char *supported_sasl_mech_attrs[] = {
     225             :                 "supportedSASLMechanisms", 
     226             :                 NULL 
     227             :         };
     228       26102 :         unsigned int logon_retries = 0;
     229         122 :         size_t queue_length;
     230             : 
     231       26102 :         if (conn->sockets.active == NULL) {
     232           0 :                 status = NT_STATUS_CONNECTION_DISCONNECTED;
     233           0 :                 goto failed;
     234             :         }
     235             : 
     236       26102 :         queue_length = tevent_queue_length(conn->sockets.send_queue);
     237       26102 :         if (queue_length != 0) {
     238           0 :                 status = NT_STATUS_INVALID_PARAMETER_MIX;
     239           0 :                 DEBUG(1, ("SASL bind triggered with non empty send_queue[%zu]: %s\n",
     240             :                           queue_length, nt_errstr(status)));
     241           0 :                 goto failed;
     242             :         }
     243             : 
     244       26102 :         if (conn->pending != NULL) {
     245           0 :                 status = NT_STATUS_INVALID_PARAMETER_MIX;
     246           0 :                 DEBUG(1, ("SASL bind triggered with pending requests: %s\n",
     247             :                           nt_errstr(status)));
     248           0 :                 goto failed;
     249             :         }
     250             : 
     251       26102 :         status = ildap_search(conn, "", LDAP_SEARCH_SCOPE_BASE, "", supported_sasl_mech_attrs,
     252             :                               false, NULL, NULL, &sasl_mechs_msgs);
     253       26102 :         if (!NT_STATUS_IS_OK(status)) {
     254           0 :                 DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: %s\n",
     255             :                           nt_errstr(status)));
     256           0 :                 goto failed;
     257             :         }
     258             : 
     259       26102 :         count = ildap_count_entries(conn, sasl_mechs_msgs);
     260       26102 :         if (count != 1) {
     261           0 :                 DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: wrong number of replies: %d\n",
     262             :                           count));
     263           0 :                 goto failed;
     264             :         }
     265             : 
     266       26102 :         tmp_ctx = talloc_new(conn);
     267       26102 :         if (tmp_ctx == NULL) goto failed;
     268             : 
     269       26102 :         search = &sasl_mechs_msgs[0]->r.SearchResultEntry;
     270       26102 :         if (search->num_attributes != 1) {
     271           0 :                 DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: wrong number of attributes: %d != 1\n",
     272             :                           search->num_attributes));
     273           0 :                 goto failed;
     274             :         }
     275             : 
     276       26102 :         sasl_names = talloc_array(tmp_ctx, const char *, search->attributes[0].num_values + 1);
     277       26102 :         if (!sasl_names) {
     278           0 :                 DEBUG(1, ("talloc_arry(char *, %d) failed\n",
     279             :                           count));
     280           0 :                 goto failed;
     281             :         }
     282             : 
     283      104408 :         for (i=0; i<search->attributes[0].num_values; i++) {
     284       78306 :                 sasl_names[i] = (const char *)search->attributes[0].values[i].data;
     285             :         }
     286       26102 :         sasl_names[i] = NULL;
     287             : 
     288       26102 :         gensec_init();
     289             : 
     290       26102 :         if (conn->sockets.active == conn->sockets.tls) {
     291             :                 /*
     292             :                  * require Kerberos SIGN/SEAL only if we don't use SSL
     293             :                  * Windows seem not to like double encryption
     294             :                  */
     295          48 :                 wrap_flags = 0;
     296       26054 :         } else if (cli_credentials_is_anonymous(creds)) {
     297             :                 /*
     298             :                  * anonymous isn't protected
     299             :                  */
     300           0 :                 wrap_flags = 0;
     301             :         } else {
     302       26054 :                 wrap_flags = lpcfg_client_ldap_sasl_wrapping(lp_ctx);
     303             :         }
     304             : 
     305       25980 : try_logon_again:
     306             :         /*
     307             :           we loop back here on a logon failure, and re-create the
     308             :           gensec session. The logon_retries counter ensures we don't
     309             :           loop forever.
     310             :          */
     311       26228 :         data_blob_free(&input);
     312       26228 :         TALLOC_FREE(conn->gensec);
     313             : 
     314       26228 :         status = gensec_client_start(conn, &conn->gensec,
     315             :                                      lpcfg_gensec_settings(conn, lp_ctx));
     316       26228 :         if (!NT_STATUS_IS_OK(status)) {
     317           0 :                 DEBUG(0, ("Failed to start GENSEC engine (%s)\n", nt_errstr(status)));
     318           0 :                 goto failed;
     319             :         }
     320             : 
     321       26228 :         old_gensec_features = cli_credentials_get_gensec_features(creds);
     322       26228 :         if (wrap_flags == 0) {
     323         177 :                 cli_credentials_set_gensec_features(creds,
     324             :                                 old_gensec_features & ~(GENSEC_FEATURE_SIGN|GENSEC_FEATURE_SEAL),
     325             :                                 CRED_SPECIFIED);
     326             :         }
     327             : 
     328             :         /* this call also sets the gensec_want_features */
     329       26228 :         status = gensec_set_credentials(conn->gensec, creds);
     330       26228 :         if (!NT_STATUS_IS_OK(status)) {
     331           0 :                 DEBUG(1, ("Failed to set GENSEC creds: %s\n", 
     332             :                           nt_errstr(status)));
     333           0 :                 goto failed;
     334             :         }
     335             : 
     336             :         /* reset the original gensec_features (on the credentials
     337             :          * context, so we don't tattoo it ) */
     338       26228 :         cli_credentials_set_gensec_features(creds,
     339             :                                             old_gensec_features,
     340             :                                             CRED_SPECIFIED);
     341             : 
     342       26228 :         if (wrap_flags & ADS_AUTH_SASL_SEAL) {
     343       25924 :                 gensec_want_feature(conn->gensec, GENSEC_FEATURE_SIGN);
     344       25924 :                 gensec_want_feature(conn->gensec, GENSEC_FEATURE_SEAL);
     345             :         }
     346       26228 :         if (wrap_flags & ADS_AUTH_SASL_SIGN) {
     347         127 :                 gensec_want_feature(conn->gensec, GENSEC_FEATURE_SIGN);
     348             :         }
     349             : 
     350             :         /*
     351             :          * This is an indication for the NTLMSSP backend to
     352             :          * also encrypt when only GENSEC_FEATURE_SIGN is requested
     353             :          * in gensec_[un]wrap().
     354             :          */
     355       26228 :         gensec_want_feature(conn->gensec, GENSEC_FEATURE_LDAP_STYLE);
     356             : 
     357       26228 :         if (conn->host) {
     358       26228 :                 status = gensec_set_target_hostname(conn->gensec, conn->host);
     359       26228 :                 if (!NT_STATUS_IS_OK(status)) {
     360           0 :                         DEBUG(1, ("Failed to set GENSEC target hostname: %s\n", 
     361             :                                   nt_errstr(status)));
     362           0 :                         goto failed;
     363             :                 }
     364             :         }
     365             : 
     366       26228 :         status = gensec_set_target_service(conn->gensec, "ldap");
     367       26228 :         if (!NT_STATUS_IS_OK(status)) {
     368           0 :                 DEBUG(1, ("Failed to set GENSEC target service: %s\n", 
     369             :                           nt_errstr(status)));
     370           0 :                 goto failed;
     371             :         }
     372             : 
     373       26228 :         status = gensec_start_mech_by_sasl_list(conn->gensec, sasl_names);
     374       26228 :         if (!NT_STATUS_IS_OK(status)) {
     375           0 :                 DEBUG(1, ("None of the %d proposed SASL mechs were acceptable: %s\n",
     376             :                           count, nt_errstr(status)));
     377           0 :                 goto failed;
     378             :         }
     379             : 
     380       34709 :         while (1) {
     381         244 :                 NTSTATUS gensec_status;
     382         244 :                 struct ldap_message *response;
     383         244 :                 struct ldap_message *msg;
     384         244 :                 struct ldap_request *req;
     385       60937 :                 int result = LDAP_OTHER;
     386             :         
     387       60937 :                 status = gensec_update(conn->gensec, tmp_ctx,
     388             :                                        input,
     389             :                                        &output);
     390             :                 /* The status value here, from GENSEC is vital to the security
     391             :                  * of the system.  Even if the other end accepts, if GENSEC
     392             :                  * claims 'MORE_PROCESSING_REQUIRED' then you must keep
     393             :                  * feeding it blobs, or else the remote host/attacker might
     394             :                  * avoid mutual authentication requirements.
     395             :                  *
     396             :                  * Likewise, you must not feed GENSEC too much (after the OK),
     397             :                  * it doesn't like that either.
     398             :                  *
     399             :                  * For SASL/EXTERNAL, there is no data to send, but we still
     400             :                  * must send the actual Bind request the first time around.
     401             :                  * Otherwise, a result of NT_STATUS_OK with 0 output means the
     402             :                  * end of a multi-step authentication, and no message must be
     403             :                  * sent.
     404             :                  */
     405             : 
     406       60937 :                 gensec_status = status;
     407             : 
     408       60937 :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) && 
     409       25903 :                     !NT_STATUS_IS_OK(status)) {
     410         272 :                         break;
     411             :                 }
     412       60665 :                 if (NT_STATUS_IS_OK(status) && output.length == 0) {
     413       25631 :                         if (!first)
     414       25509 :                                 break;
     415             :                 }
     416       35034 :                 first = false;
     417             : 
     418             :                 /* Perhaps we should make gensec_start_mech_by_sasl_list() return the name we got? */
     419       35034 :                 msg = new_ldap_sasl_bind_msg(tmp_ctx, conn->gensec->ops->sasl_name, (output.data?&output:NULL));
     420       35034 :                 if (msg == NULL) {
     421           0 :                         status = NT_STATUS_NO_MEMORY;
     422           0 :                         goto failed;
     423             :                 }
     424             : 
     425       35034 :                 req = ldap_request_send(conn, msg);
     426       35034 :                 if (req == NULL) {
     427           0 :                         status = NT_STATUS_NO_MEMORY;
     428           0 :                         goto failed;
     429             :                 }
     430       35034 :                 talloc_reparent(conn, tmp_ctx, req);
     431             : 
     432       35034 :                 status = ldap_result_n(req, 0, &response);
     433       35034 :                 if (!NT_STATUS_IS_OK(status)) {
     434           0 :                         goto failed;
     435             :                 }
     436             :                 
     437       35034 :                 if (response->type != LDAP_TAG_BindResponse) {
     438           0 :                         status = NT_STATUS_UNEXPECTED_NETWORK_ERROR;
     439           0 :                         goto failed;
     440             :                 }
     441             : 
     442       35034 :                 result = response->r.BindResponse.response.resultcode;
     443             : 
     444       35034 :                 if (result == LDAP_STRONG_AUTH_REQUIRED) {
     445         125 :                         if (wrap_flags == 0) {
     446         125 :                                 wrap_flags = ADS_AUTH_SASL_SIGN;
     447         126 :                                 goto try_logon_again;
     448             :                         }
     449             :                 }
     450             : 
     451       34909 :                 if (result == LDAP_INVALID_CREDENTIALS) {
     452             :                         /*
     453             :                           try a second time on invalid credentials, to
     454             :                           give the user a chance to re-enter the
     455             :                           password and to handle the case where our
     456             :                           kerberos ticket is invalid as the server
     457             :                           password has changed
     458             :                         */
     459           0 :                         const char *principal;
     460             : 
     461         197 :                         principal = gensec_get_target_principal(conn->gensec);
     462         197 :                         if (principal == NULL) {
     463         197 :                                 const char *hostname = gensec_get_target_hostname(conn->gensec);
     464         197 :                                 const char *service  = gensec_get_target_service(conn->gensec);
     465         197 :                                 if (hostname != NULL && service != NULL) {
     466         197 :                                         principal = talloc_asprintf(tmp_ctx, "%s/%s", service, hostname);
     467             :                                 }
     468             :                         }
     469             : 
     470         393 :                         if (cli_credentials_failed_kerberos_login(creds, principal, &logon_retries) ||
     471         196 :                             cli_credentials_wrong_password(creds)) {
     472             :                                 /*
     473             :                                   destroy our gensec session and loop
     474             :                                   back up to the top to retry,
     475             :                                   offering the user a chance to enter
     476             :                                   new credentials, or get a new ticket
     477             :                                   if using kerberos
     478             :                                  */
     479           1 :                                 goto try_logon_again;
     480             :                         }
     481             :                 }
     482             : 
     483       34908 :                 if (result != LDAP_SUCCESS && result != LDAP_SASL_BIND_IN_PROGRESS) {
     484         199 :                         status = ldap_check_response(conn, 
     485         199 :                                                      &response->r.BindResponse.response);
     486         199 :                         break;
     487             :                 }
     488             : 
     489             :                 /* This is where we check if GENSEC wanted to be fed more data */
     490       34709 :                 if (!NT_STATUS_EQUAL(gensec_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
     491           0 :                         break;
     492             :                 }
     493       34709 :                 if (response->r.BindResponse.SASL.secblob) {
     494       34709 :                         input = *response->r.BindResponse.SASL.secblob;
     495             :                 } else {
     496           0 :                         input = data_blob(NULL, 0);
     497             :                 }
     498             :         }
     499             : 
     500       26102 :         TALLOC_FREE(tmp_ctx);
     501             : 
     502       26102 :         if (!NT_STATUS_IS_OK(status)) {
     503         471 :                 goto failed;
     504             :         }
     505             : 
     506       25631 :         conn->bind.type = LDAP_BIND_SASL;
     507       25631 :         conn->bind.creds = creds;
     508             : 
     509       25631 :         if (wrap_flags & ADS_AUTH_SASL_SEAL) {
     510       25454 :                 if (!gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN)) {
     511           0 :                         return NT_STATUS_INVALID_NETWORK_RESPONSE;
     512             :                 }
     513             : 
     514       25454 :                 if (!gensec_have_feature(conn->gensec, GENSEC_FEATURE_SEAL)) {
     515           0 :                         return NT_STATUS_INVALID_NETWORK_RESPONSE;
     516             :                 }
     517         177 :         } else if (wrap_flags & ADS_AUTH_SASL_SIGN) {
     518         125 :                 if (!gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN)) {
     519           0 :                         return NT_STATUS_INVALID_NETWORK_RESPONSE;
     520             :                 }
     521             :         }
     522             : 
     523       25631 :         if (!gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN) &&
     524          52 :             !gensec_have_feature(conn->gensec, GENSEC_FEATURE_SEAL)) {
     525          52 :                 return NT_STATUS_OK;
     526             :         }
     527             : 
     528       25579 :         status = gensec_create_tstream(conn->sockets.raw,
     529             :                                        conn->gensec,
     530             :                                        conn->sockets.raw,
     531             :                                        &conn->sockets.sasl);
     532       25579 :         if (!NT_STATUS_IS_OK(status)) {
     533           0 :                 goto failed;
     534             :         }
     535             : 
     536       25579 :         conn->sockets.active = conn->sockets.sasl;
     537             : 
     538       25579 :         return NT_STATUS_OK;
     539             : 
     540         471 : failed:
     541         471 :         talloc_free(tmp_ctx);
     542         471 :         talloc_free(conn->gensec);
     543         471 :         conn->gensec = NULL;
     544         471 :         return status;
     545             : }

Generated by: LCOV version 1.14