LCOV - code coverage report
Current view: top level - source4/librpc/rpc - dcerpc_auth.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 198 232 85.3 %
Date: 2024-04-21 15:09:00 Functions: 13 13 100.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    Generic Authentication Interface
       5             : 
       6             :    Copyright (C) Andrew Tridgell 2003
       7             :    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005
       8             :    Copyright (C) Stefan Metzmacher 2004
       9             :    
      10             :    This program is free software; you can redistribute it and/or modify
      11             :    it under the terms of the GNU General Public License as published by
      12             :    the Free Software Foundation; either version 3 of the License, or
      13             :    (at your option) any later version.
      14             :    
      15             :    This program is distributed in the hope that it will be useful,
      16             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             :    GNU General Public License for more details.
      19             :    
      20             :    You should have received a copy of the GNU General Public License
      21             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      22             : */
      23             : 
      24             : #include "includes.h"
      25             : #include <tevent.h>
      26             : #include "libcli/composite/composite.h"
      27             : #include "auth/gensec/gensec.h"
      28             : #include "librpc/rpc/dcerpc.h"
      29             : #include "librpc/rpc/dcerpc_proto.h"
      30             : #include "param/param.h"
      31             : 
      32             : /*
      33             :   return the rpc syntax and transfer syntax given the pipe uuid and version
      34             : */
      35       20179 : static NTSTATUS dcerpc_init_syntaxes(struct dcerpc_pipe *p,
      36             :                                      const struct ndr_interface_table *table,
      37             :                                      struct ndr_syntax_id *syntax,
      38             :                                      struct ndr_syntax_id *transfer_syntax)
      39             : {
      40       20179 :         struct GUID *object = NULL;
      41             : 
      42       20179 :         p->object = dcerpc_binding_get_object(p->binding);
      43       20179 :         if (!GUID_all_zero(&p->object)) {
      44          10 :                 object = &p->object;
      45             :         }
      46             : 
      47       20179 :         p->binding_handle = dcerpc_pipe_binding_handle(p, object, table);
      48       20179 :         if (p->binding_handle == NULL) {
      49           0 :                 return NT_STATUS_NO_MEMORY;
      50             :         }
      51             : 
      52       20179 :         syntax->uuid = table->syntax_id.uuid;
      53       20179 :         syntax->if_version = table->syntax_id.if_version;
      54             : 
      55       20179 :         if (p->conn->flags & DCERPC_NDR64) {
      56           0 :                 *transfer_syntax = ndr_transfer_syntax_ndr64;
      57             :         } else {
      58       20179 :                 *transfer_syntax = ndr_transfer_syntax_ndr;
      59             :         }
      60             : 
      61       20179 :         return NT_STATUS_OK;
      62             : }
      63             : 
      64             : 
      65             : /*
      66             :   Send request to do a non-authenticated dcerpc bind
      67             : */
      68             : static void dcerpc_bind_auth_none_done(struct tevent_req *subreq);
      69             : 
      70       11420 : struct composite_context *dcerpc_bind_auth_none_send(TALLOC_CTX *mem_ctx,
      71             :                                                      struct dcerpc_pipe *p,
      72             :                                                      const struct ndr_interface_table *table)
      73             : {
      74         440 :         struct ndr_syntax_id syntax;
      75         440 :         struct ndr_syntax_id transfer_syntax;
      76             : 
      77         440 :         struct composite_context *c;
      78         440 :         struct tevent_req *subreq;
      79             : 
      80       11420 :         c = composite_create(mem_ctx, p->conn->event_ctx);
      81       11420 :         if (c == NULL) return NULL;
      82             : 
      83       11420 :         c->status = dcerpc_init_syntaxes(p, table,
      84             :                                          &syntax, &transfer_syntax);
      85       11420 :         if (!NT_STATUS_IS_OK(c->status)) {
      86           0 :                 DEBUG(2,("Invalid uuid string in "
      87             :                          "dcerpc_bind_auth_none_send\n"));
      88           0 :                 composite_error(c, c->status);
      89           0 :                 return c;
      90             :         }
      91             : 
      92       11420 :         subreq = dcerpc_bind_send(mem_ctx, p->conn->event_ctx, p,
      93             :                                   &syntax, &transfer_syntax);
      94       11420 :         if (composite_nomem(subreq, c)) return c;
      95       11420 :         tevent_req_set_callback(subreq, dcerpc_bind_auth_none_done, c);
      96             : 
      97       11420 :         return c;
      98             : }
      99             : 
     100       11420 : static void dcerpc_bind_auth_none_done(struct tevent_req *subreq)
     101             : {
     102         440 :         struct composite_context *ctx =
     103       11420 :                 tevent_req_callback_data(subreq,
     104             :                 struct composite_context);
     105             : 
     106       11420 :         ctx->status = dcerpc_bind_recv(subreq);
     107       11420 :         TALLOC_FREE(subreq);
     108       11420 :         if (!composite_is_ok(ctx)) return;
     109             : 
     110       11351 :         composite_done(ctx);
     111             : }
     112             : 
     113             : /*
     114             :   Receive result of a non-authenticated dcerpc bind
     115             : */
     116       11420 : NTSTATUS dcerpc_bind_auth_none_recv(struct composite_context *ctx)
     117             : {
     118       11420 :         NTSTATUS result = composite_wait(ctx);
     119       11420 :         TALLOC_FREE(ctx);
     120       11420 :         return result;
     121             : }
     122             : 
     123             : 
     124             : /*
     125             :   Perform sync non-authenticated dcerpc bind
     126             : */
     127         175 : _PUBLIC_ NTSTATUS dcerpc_bind_auth_none(struct dcerpc_pipe *p,
     128             :                                const struct ndr_interface_table *table)
     129             : {
     130           0 :         struct composite_context *ctx;
     131             : 
     132         175 :         ctx = dcerpc_bind_auth_none_send(p, p, table);
     133         175 :         return dcerpc_bind_auth_none_recv(ctx);
     134             : }
     135             : 
     136             : 
     137             : struct bind_auth_state {
     138             :         struct dcerpc_pipe *pipe;
     139             :         struct ndr_syntax_id syntax;
     140             :         struct ndr_syntax_id transfer_syntax;
     141             :         struct dcerpc_auth out_auth_info;
     142             :         struct dcerpc_auth in_auth_info;
     143             :         bool more_processing;   /* Is there anything more to do after the
     144             :                                  * first bind itself received? */
     145             : };
     146             : 
     147             : static void bind_auth_next_gensec_done(struct tevent_req *subreq);
     148             : static void bind_auth_recv_alter(struct tevent_req *subreq);
     149             : 
     150       14434 : static void bind_auth_next_step(struct composite_context *c)
     151             : {
     152         520 :         struct bind_auth_state *state;
     153         520 :         struct dcecli_security *sec;
     154         520 :         struct tevent_req *subreq;
     155             : 
     156       14434 :         state = talloc_get_type(c->private_data, struct bind_auth_state);
     157       14434 :         sec = &state->pipe->conn->security_state;
     158             : 
     159       14434 :         if (state->in_auth_info.auth_type != sec->auth_type) {
     160           0 :                 composite_error(c, NT_STATUS_RPC_PROTOCOL_ERROR);
     161           0 :                 return;
     162             :         }
     163             : 
     164       14434 :         if (state->in_auth_info.auth_level != sec->auth_level) {
     165           0 :                 composite_error(c, NT_STATUS_RPC_PROTOCOL_ERROR);
     166           0 :                 return;
     167             :         }
     168             : 
     169       14434 :         if (state->in_auth_info.auth_context_id != sec->auth_context_id) {
     170           0 :                 composite_error(c, NT_STATUS_RPC_PROTOCOL_ERROR);
     171           0 :                 return;
     172             :         }
     173             : 
     174       14434 :         state->out_auth_info = (struct dcerpc_auth) {
     175       13914 :                 .auth_type = sec->auth_type,
     176       13914 :                 .auth_level = sec->auth_level,
     177       13914 :                 .auth_context_id = sec->auth_context_id,
     178             :         };
     179             : 
     180             :         /* The status value here, from GENSEC is vital to the security
     181             :          * of the system.  Even if the other end accepts, if GENSEC
     182             :          * claims 'MORE_PROCESSING_REQUIRED' then you must keep
     183             :          * feeding it blobs, or else the remote host/attacker might
     184             :          * avoid mutual authentication requirements.
     185             :          *
     186             :          * Likewise, you must not feed GENSEC too much (after the OK),
     187             :          * it doesn't like that either
     188             :          */
     189             : 
     190       14434 :         state->pipe->inhibit_timeout_processing = true;
     191       14434 :         state->pipe->timed_out = false;
     192             : 
     193       14434 :         subreq = gensec_update_send(state,
     194       13914 :                                     state->pipe->conn->event_ctx,
     195             :                                     sec->generic_state,
     196             :                                     state->in_auth_info.credentials);
     197       14434 :         if (composite_nomem(subreq, c)) return;
     198       14434 :         tevent_req_set_callback(subreq, bind_auth_next_gensec_done, c);
     199             : }
     200             : 
     201       14434 : static void bind_auth_next_gensec_done(struct tevent_req *subreq)
     202             : {
     203         520 :         struct composite_context *c =
     204       14434 :                 tevent_req_callback_data(subreq,
     205             :                 struct composite_context);
     206         520 :         struct bind_auth_state *state =
     207       14434 :                 talloc_get_type_abort(c->private_data,
     208             :                 struct bind_auth_state);
     209       14434 :         struct dcerpc_pipe *p = state->pipe;
     210       14434 :         struct dcecli_security *sec = &p->conn->security_state;
     211       14434 :         bool more_processing = false;
     212             : 
     213       14434 :         state->pipe->inhibit_timeout_processing = false;
     214             : 
     215       14434 :         c->status = gensec_update_recv(subreq, state,
     216             :                                        &state->out_auth_info.credentials);
     217       14434 :         TALLOC_FREE(subreq);
     218             : 
     219       14434 :         if (NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
     220        5730 :                 more_processing = true;
     221        5730 :                 c->status = NT_STATUS_OK;
     222             :         }
     223             : 
     224       22714 :         if (!composite_is_ok(c)) return;
     225             : 
     226       14434 :         if (!more_processing) {
     227        8704 :                 if (state->pipe->conn->flags & DCERPC_HEADER_SIGNING) {
     228        7730 :                         gensec_want_feature(sec->generic_state,
     229             :                                         GENSEC_FEATURE_SIGN_PKT_HEADER);
     230             :                 }
     231             :         }
     232             : 
     233       14434 :         if (state->out_auth_info.credentials.length == 0) {
     234        8519 :                 composite_done(c);
     235        8519 :                 return;
     236             :         }
     237             : 
     238        5915 :         state->in_auth_info = (struct dcerpc_auth) {
     239             :                 .auth_type = DCERPC_AUTH_TYPE_NONE,
     240             :         };
     241        5915 :         sec->tmp_auth_info.in = &state->in_auth_info;
     242        5915 :         sec->tmp_auth_info.mem = state;
     243        5915 :         sec->tmp_auth_info.out = &state->out_auth_info;
     244             : 
     245        5915 :         if (!more_processing) {
     246             :                 /* NO reply expected, so just send it */
     247         185 :                 c->status = dcerpc_auth3(state->pipe, state);
     248         185 :                 if (!composite_is_ok(c)) return;
     249             : 
     250         185 :                 composite_done(c);
     251         185 :                 return;
     252             :         }
     253             : 
     254             :         /* We are demanding a reply, so use a request that will get us one */
     255             : 
     256        5826 :         subreq = dcerpc_alter_context_send(state, state->pipe->conn->event_ctx,
     257             :                                            state->pipe,
     258        5730 :                                            &state->pipe->syntax,
     259        5730 :                                            &state->pipe->transfer_syntax);
     260        5730 :         if (composite_nomem(subreq, c)) return;
     261        5730 :         tevent_req_set_callback(subreq, bind_auth_recv_alter, c);
     262             : }
     263             : 
     264             : 
     265        5730 : static void bind_auth_recv_alter(struct tevent_req *subreq)
     266             : {
     267          96 :         struct composite_context *c =
     268        5730 :                 tevent_req_callback_data(subreq,
     269             :                 struct composite_context);
     270        5730 :         struct bind_auth_state *state = talloc_get_type(c->private_data,
     271             :                                                         struct bind_auth_state);
     272        5730 :         struct dcecli_security *sec = &state->pipe->conn->security_state;
     273             : 
     274        5730 :         ZERO_STRUCT(sec->tmp_auth_info);
     275             : 
     276        5730 :         c->status = dcerpc_alter_context_recv(subreq);
     277        5730 :         TALLOC_FREE(subreq);
     278        5730 :         if (!composite_is_ok(c)) return;
     279             : 
     280        5730 :         bind_auth_next_step(c);
     281             : }
     282             : 
     283             : 
     284        8735 : static void bind_auth_recv_bindreply(struct tevent_req *subreq)
     285             : {
     286         430 :         struct composite_context *c =
     287        8735 :                 tevent_req_callback_data(subreq,
     288             :                 struct composite_context);
     289        8735 :         struct bind_auth_state *state = talloc_get_type(c->private_data,
     290             :                                                         struct bind_auth_state);
     291        8735 :         struct dcecli_security *sec = &state->pipe->conn->security_state;
     292             : 
     293        8735 :         ZERO_STRUCT(sec->tmp_auth_info);
     294             : 
     295        8735 :         c->status = dcerpc_bind_recv(subreq);
     296        8735 :         TALLOC_FREE(subreq);
     297        8735 :         if (!composite_is_ok(c)) return;
     298             : 
     299        8704 :         if (!state->more_processing) {
     300             :                 /* The first gensec_update has not requested a second run, so
     301             :                  * we're done here. */
     302           0 :                 composite_done(c);
     303           0 :                 return;
     304             :         }
     305             : 
     306        8704 :         bind_auth_next_step(c);
     307             : }
     308             : 
     309             : 
     310             : static void dcerpc_bind_auth_gensec_done(struct tevent_req *subreq);
     311             : 
     312             : /**
     313             :    Bind to a DCE/RPC pipe, send async request
     314             :    @param mem_ctx TALLOC_CTX for the allocation of the composite_context
     315             :    @param p The dcerpc_pipe to bind (must already be connected)
     316             :    @param table The interface table to use (the DCE/RPC bind both selects and interface and authenticates)
     317             :    @param credentials The credentials of the account to connect with 
     318             :    @param auth_type Select the authentication scheme to use
     319             :    @param auth_level Chooses between unprotected (connect), signed or sealed
     320             :    @param service The service (used by Kerberos to select the service principal to contact)
     321             :    @retval A composite context describing the partial state of the bind
     322             : */
     323             : 
     324        8759 : struct composite_context *dcerpc_bind_auth_send(TALLOC_CTX *mem_ctx,
     325             :                                                 struct dcerpc_pipe *p,
     326             :                                                 const struct ndr_interface_table *table,
     327             :                                                 struct cli_credentials *credentials,
     328             :                                                 struct gensec_settings *gensec_settings,
     329             :                                                 uint8_t auth_type, uint8_t auth_level,
     330             :                                                 const char *service)
     331             : {
     332         430 :         struct composite_context *c;
     333         430 :         struct bind_auth_state *state;
     334         430 :         struct dcecli_security *sec;
     335         430 :         struct tevent_req *subreq;
     336        8759 :         const char *target_principal = NULL;
     337             : 
     338             :         /* composite context allocation and setup */
     339        8759 :         c = composite_create(mem_ctx, p->conn->event_ctx);
     340        8759 :         if (c == NULL) return NULL;
     341             : 
     342        8759 :         state = talloc(c, struct bind_auth_state);
     343        8759 :         if (composite_nomem(state, c)) return c;
     344        8759 :         c->private_data = state;
     345             : 
     346        8759 :         state->pipe = p;
     347             : 
     348        8759 :         c->status = dcerpc_init_syntaxes(p, table,
     349             :                                          &state->syntax,
     350             :                                          &state->transfer_syntax);
     351        8759 :         if (!composite_is_ok(c)) return c;
     352             : 
     353        8759 :         sec = &p->conn->security_state;
     354             : 
     355        8759 :         c->status = gensec_client_start(p, &sec->generic_state,
     356             :                                         gensec_settings);
     357        8759 :         if (!NT_STATUS_IS_OK(c->status)) {
     358           0 :                 DEBUG(1, ("Failed to start GENSEC client mode: %s\n",
     359             :                           nt_errstr(c->status)));
     360           0 :                 composite_error(c, c->status);
     361           0 :                 return c;
     362             :         }
     363             : 
     364        8759 :         c->status = gensec_set_credentials(sec->generic_state, credentials);
     365        8759 :         if (!NT_STATUS_IS_OK(c->status)) {
     366           0 :                 DEBUG(1, ("Failed to set GENSEC client credentials: %s\n",
     367             :                           nt_errstr(c->status)));
     368           0 :                 composite_error(c, c->status);
     369           0 :                 return c;
     370             :         }
     371             : 
     372        8759 :         c->status = gensec_set_target_hostname(sec->generic_state,
     373             :                                                dcerpc_server_name(p));
     374        8759 :         if (!NT_STATUS_IS_OK(c->status)) {
     375           0 :                 DEBUG(1, ("Failed to set GENSEC target hostname: %s\n", 
     376             :                           nt_errstr(c->status)));
     377           0 :                 composite_error(c, c->status);
     378           0 :                 return c;
     379             :         }
     380             : 
     381        8759 :         if (service != NULL) {
     382        8258 :                 c->status = gensec_set_target_service(sec->generic_state,
     383             :                                                       service);
     384        8258 :                 if (!NT_STATUS_IS_OK(c->status)) {
     385           0 :                         DEBUG(1, ("Failed to set GENSEC target service: %s\n",
     386             :                                   nt_errstr(c->status)));
     387           0 :                         composite_error(c, c->status);
     388           0 :                         return c;
     389             :                 }
     390             :         }
     391             : 
     392        8759 :         if (p->binding != NULL) {
     393        8759 :                 target_principal = dcerpc_binding_get_string_option(p->binding,
     394             :                                                         "target_principal");
     395             :         }
     396        8759 :         if (target_principal != NULL) {
     397         209 :                 c->status = gensec_set_target_principal(sec->generic_state,
     398             :                                                         target_principal);
     399         209 :                 if (!NT_STATUS_IS_OK(c->status)) {
     400           0 :                         DEBUG(1, ("Failed to set GENSEC target principal to %s: %s\n",
     401             :                                   target_principal, nt_errstr(c->status)));
     402           0 :                         composite_error(c, c->status);
     403           0 :                         return c;
     404             :                 }
     405             :         }
     406             : 
     407        8759 :         c->status = gensec_start_mech_by_authtype(sec->generic_state,
     408             :                                                   auth_type, auth_level);
     409        8759 :         if (!NT_STATUS_IS_OK(c->status)) {
     410          24 :                 DEBUG(1, ("Failed to start GENSEC client mechanism %s: %s\n",
     411             :                           gensec_get_name_by_authtype(sec->generic_state, auth_type),
     412             :                           nt_errstr(c->status)));
     413          24 :                 composite_error(c, c->status);
     414          24 :                 return c;
     415             :         }
     416             : 
     417        8735 :         sec->auth_type = auth_type;
     418        8735 :         sec->auth_level = auth_level,
     419             :         /*
     420             :          * We use auth_context_id = 1 as some older
     421             :          * Samba versions (<= 4.2.3) use that value hardcoded
     422             :          * in a response.
     423             :          */
     424        8735 :         sec->auth_context_id = 1;
     425             : 
     426        8735 :         state->out_auth_info = (struct dcerpc_auth) {
     427        8305 :                 .auth_type = sec->auth_type,
     428        8305 :                 .auth_level = sec->auth_level,
     429        8305 :                 .auth_context_id = sec->auth_context_id,
     430             :         };
     431             : 
     432             :         /* The status value here, from GENSEC is vital to the security
     433             :          * of the system.  Even if the other end accepts, if GENSEC
     434             :          * claims 'MORE_PROCESSING_REQUIRED' then you must keep
     435             :          * feeding it blobs, or else the remote host/attacker might
     436             :          * avoid mutual authentication requirements.
     437             :          *
     438             :          * Likewise, you must not feed GENSEC too much (after the OK),
     439             :          * it doesn't like that either
     440             :          */
     441             : 
     442        8735 :         state->pipe->inhibit_timeout_processing = true;
     443        8735 :         state->pipe->timed_out = false;
     444             : 
     445        9165 :         subreq = gensec_update_send(state,
     446        8735 :                                     p->conn->event_ctx,
     447             :                                     sec->generic_state,
     448             :                                     data_blob_null);
     449        8735 :         if (composite_nomem(subreq, c)) return c;
     450        8735 :         tevent_req_set_callback(subreq, dcerpc_bind_auth_gensec_done, c);
     451             : 
     452        8735 :         return c;
     453             : }
     454             : 
     455        8735 : static void dcerpc_bind_auth_gensec_done(struct tevent_req *subreq)
     456             : {
     457         430 :         struct composite_context *c =
     458        8735 :                 tevent_req_callback_data(subreq,
     459             :                 struct composite_context);
     460         430 :         struct bind_auth_state *state =
     461        8735 :                 talloc_get_type_abort(c->private_data,
     462             :                 struct bind_auth_state);
     463        8735 :         struct dcerpc_pipe *p = state->pipe;
     464        8735 :         struct dcecli_security *sec = &p->conn->security_state;
     465             : 
     466        8735 :         state->pipe->inhibit_timeout_processing = false;
     467             : 
     468        8735 :         c->status = gensec_update_recv(subreq, state,
     469             :                                        &state->out_auth_info.credentials);
     470        8735 :         TALLOC_FREE(subreq);
     471        8735 :         if (!NT_STATUS_IS_OK(c->status) &&
     472        8305 :             !NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
     473           0 :                 composite_error(c, c->status);
     474           0 :                 return;
     475             :         }
     476             : 
     477        8735 :         state->more_processing = NT_STATUS_EQUAL(c->status,
     478             :                                                  NT_STATUS_MORE_PROCESSING_REQUIRED);
     479             : 
     480        8735 :         if (state->out_auth_info.credentials.length == 0) {
     481           0 :                 composite_done(c);
     482           0 :                 return;
     483             :         }
     484             : 
     485        8735 :         if (gensec_have_feature(sec->generic_state, GENSEC_FEATURE_SIGN_PKT_HEADER)) {
     486        8295 :                 if (sec->auth_level >= DCERPC_AUTH_LEVEL_PACKET) {
     487        8259 :                         state->pipe->conn->flags |= DCERPC_PROPOSE_HEADER_SIGNING;
     488             :                 }
     489             :         }
     490             : 
     491        8735 :         state->in_auth_info = (struct dcerpc_auth) {
     492             :                 .auth_type = DCERPC_AUTH_TYPE_NONE,
     493             :         };
     494        8735 :         sec->tmp_auth_info.in = &state->in_auth_info;
     495        8735 :         sec->tmp_auth_info.mem = state;
     496        8735 :         sec->tmp_auth_info.out = &state->out_auth_info;
     497             : 
     498             :         /* The first request always is a dcerpc_bind. The subsequent ones
     499             :          * depend on gensec results */
     500        9165 :         subreq = dcerpc_bind_send(state, p->conn->event_ctx, p,
     501        8735 :                                   &state->syntax, &state->transfer_syntax);
     502        8735 :         if (composite_nomem(subreq, c)) return;
     503        8735 :         tevent_req_set_callback(subreq, bind_auth_recv_bindreply, c);
     504             : 
     505        8735 :         return;
     506             : }
     507             : 
     508             : 
     509             : /**
     510             :    Bind to a DCE/RPC pipe, receive result
     511             :    @param creq A composite context describing state of async call
     512             :    @retval NTSTATUS code
     513             : */
     514             : 
     515        8759 : NTSTATUS dcerpc_bind_auth_recv(struct composite_context *creq)
     516             : {
     517        8759 :         NTSTATUS result = composite_wait(creq);
     518        8759 :         struct bind_auth_state *state = talloc_get_type(creq->private_data,
     519             :                                                         struct bind_auth_state);
     520             : 
     521        8759 :         if (NT_STATUS_IS_OK(result)) {
     522             :                 /*
     523             :                   after a successful authenticated bind the session
     524             :                   key reverts to the generic session key
     525             :                 */
     526        8704 :                 state->pipe->conn->security_state.session_key = dcecli_generic_session_key;
     527             :         }
     528             :         
     529        8759 :         talloc_free(creq);
     530        8759 :         return result;
     531             : }
     532             : 
     533             : 
     534             : /**
     535             :    Perform a GENSEC authenticated bind to a DCE/RPC pipe, sync
     536             :    @param p The dcerpc_pipe to bind (must already be connected)
     537             :    @param table The interface table to use (the DCE/RPC bind both selects and interface and authenticates)
     538             :    @param credentials The credentials of the account to connect with 
     539             :    @param auth_type Select the authentication scheme to use
     540             :    @param auth_level Chooses between unprotected (connect), signed or sealed
     541             :    @param service The service (used by Kerberos to select the service principal to contact)
     542             :    @retval NTSTATUS status code
     543             : */
     544             : 
     545          32 : _PUBLIC_ NTSTATUS dcerpc_bind_auth(struct dcerpc_pipe *p,
     546             :                           const struct ndr_interface_table *table,
     547             :                           struct cli_credentials *credentials,
     548             :                           struct gensec_settings *gensec_settings,
     549             :                           uint8_t auth_type, uint8_t auth_level,
     550             :                           const char *service)
     551             : {
     552           0 :         struct composite_context *creq;
     553          32 :         creq = dcerpc_bind_auth_send(p, p, table, credentials, gensec_settings,
     554             :                                      auth_type, auth_level, service);
     555          32 :         return dcerpc_bind_auth_recv(creq);
     556             : }

Generated by: LCOV version 1.14