Ignore:
Timestamp:
Nov 24, 2016, 1:14:11 PM (9 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to version 4.4.3

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source3/libads/authdata.c

    r740 r988  
    2727#include "smb_krb5.h"
    2828#include "libads/kerberos_proto.h"
     29#include "auth/common_auth.h"
     30#include "lib/param/param.h"
     31#include "librpc/crypto/gse.h"
     32#include "auth/gensec/gensec.h"
     33#include "auth/gensec/gensec_internal.h" /* TODO: remove this */
     34#include "../libcli/auth/spnego.h"
    2935
    3036#ifdef HAVE_KRB5
    3137
     38#include "auth/kerberos/pac_utils.h"
     39
     40struct smb_krb5_context;
     41
    3242/****************************************************************
     43Callback to get the PAC_LOGON_INFO from the blob
    3344****************************************************************/
    34 
    35 static krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx,
    36                                           DATA_BLOB pac_data,
    37                                           struct PAC_SIGNATURE_DATA *sig,
    38                                           krb5_context context,
    39                                           krb5_keyblock *keyblock)
     45static NTSTATUS kerberos_fetch_pac(struct auth4_context *auth_ctx,
     46                                   TALLOC_CTX *mem_ctx,
     47                                   struct smb_krb5_context *smb_krb5_context,
     48                                   DATA_BLOB *pac_blob,
     49                                   const char *princ_name,
     50                                   const struct tsocket_address *remote_address,
     51                                   uint32_t session_info_flags,
     52                                   struct auth_session_info **session_info)
    4053{
    41         krb5_error_code ret;
    42         krb5_checksum cksum;
    43         krb5_keyusage usage = 0;
    44 
    45         smb_krb5_checksum_from_pac_sig(&cksum, sig);
    46 
    47 #ifdef HAVE_KRB5_KU_OTHER_CKSUM /* Heimdal */
    48         usage = KRB5_KU_OTHER_CKSUM;
    49 #elif defined(HAVE_KRB5_KEYUSAGE_APP_DATA_CKSUM) /* MIT */
    50         usage = KRB5_KEYUSAGE_APP_DATA_CKSUM;
    51 #else
    52 #error UNKNOWN_KRB5_KEYUSAGE
    53 #endif
    54 
    55         ret = smb_krb5_verify_checksum(context,
    56                                        keyblock,
    57                                        usage,
    58                                        &cksum,
    59                                        pac_data.data,
    60                                        pac_data.length);
    61 
    62         if (ret) {
    63                 DEBUG(2,("check_pac_checksum: PAC Verification failed: %s (%d)\n",
    64                         error_message(ret), ret));
    65                 return ret;
    66         }
    67 
    68         return ret;
     54        TALLOC_CTX *tmp_ctx;
     55        struct PAC_DATA *pac_data = NULL;
     56        struct PAC_DATA_CTR *pac_data_ctr = NULL;
     57        NTSTATUS status = NT_STATUS_INTERNAL_ERROR;
     58
     59        tmp_ctx = talloc_new(mem_ctx);
     60        if (!tmp_ctx) {
     61                return NT_STATUS_NO_MEMORY;
     62        }
     63
     64        if (pac_blob != NULL) {
     65                status = kerberos_decode_pac(tmp_ctx,
     66                                             *pac_blob,
     67                                             NULL,
     68                                             NULL,
     69                                             NULL,
     70                                             NULL,
     71                                             0,
     72                                             &pac_data);
     73                if (!NT_STATUS_IS_OK(status)) {
     74                        goto done;
     75                }
     76
     77                pac_data_ctr = talloc(mem_ctx, struct PAC_DATA_CTR);
     78                if (pac_data_ctr == NULL) {
     79                        status = NT_STATUS_NO_MEMORY;
     80                        goto done;
     81                }
     82
     83                talloc_set_name_const(pac_data_ctr, "struct PAC_DATA_CTR");
     84
     85                pac_data_ctr->pac_data = talloc_steal(pac_data_ctr, pac_data);
     86                pac_data_ctr->pac_blob = data_blob_talloc(pac_data_ctr,
     87                                                          pac_blob->data,
     88                                                          pac_blob->length);
     89
     90                auth_ctx->private_data = talloc_steal(auth_ctx, pac_data_ctr);
     91        }
     92
     93        *session_info = talloc_zero(mem_ctx, struct auth_session_info);
     94        if (!*session_info) {
     95                status = NT_STATUS_NO_MEMORY;
     96                goto done;
     97        }
     98        status = NT_STATUS_OK;
     99
     100done:
     101        TALLOC_FREE(tmp_ctx);
     102
     103        return status;
    69104}
    70105
    71 /**
    72 * @brief Decode a blob containing a NDR envoded PAC structure
    73 *
    74 * @param mem_ctx          - The memory context
    75 * @param pac_data_blob    - The data blob containing the NDR encoded data
    76 * @param context          - The Kerberos Context
    77 * @param service_keyblock - The Service Key used to verify the checksum
    78 * @param client_principal - The client principal
    79 * @param tgs_authtime     - The ticket timestamp
    80 * @param pac_data_out     - [out] The decoded PAC
    81 *
    82 * @return - A NTSTATUS error code
    83 */
    84 NTSTATUS decode_pac_data(TALLOC_CTX *mem_ctx,
    85                          DATA_BLOB *pac_data_blob,
    86                          krb5_context context,
    87                          krb5_keyblock *service_keyblock,
    88                          krb5_const_principal client_principal,
    89                          time_t tgs_authtime,
    90                          struct PAC_DATA **pac_data_out)
    91 {
    92         NTSTATUS status;
    93         enum ndr_err_code ndr_err;
    94         krb5_error_code ret;
    95         DATA_BLOB modified_pac_blob;
    96 
    97         NTTIME tgs_authtime_nttime;
    98         krb5_principal client_principal_pac = NULL;
    99         int i;
    100 
    101         struct PAC_SIGNATURE_DATA *srv_sig_ptr = NULL;
    102         struct PAC_SIGNATURE_DATA *kdc_sig_ptr = NULL;
    103         struct PAC_SIGNATURE_DATA *srv_sig_wipe = NULL;
    104         struct PAC_SIGNATURE_DATA *kdc_sig_wipe = NULL;
    105         struct PAC_LOGON_NAME *logon_name = NULL;
    106         struct PAC_LOGON_INFO *logon_info = NULL;
    107         struct PAC_DATA *pac_data = NULL;
    108         struct PAC_DATA_RAW *pac_data_raw = NULL;
    109 
    110         DATA_BLOB *srv_sig_blob = NULL;
    111         DATA_BLOB *kdc_sig_blob = NULL;
    112 
    113         bool bool_ret;
    114 
    115         *pac_data_out = NULL;
    116 
    117         pac_data = TALLOC_ZERO_P(mem_ctx, struct PAC_DATA);
    118         pac_data_raw = TALLOC_ZERO_P(mem_ctx, struct PAC_DATA_RAW);
    119         kdc_sig_wipe = TALLOC_ZERO_P(mem_ctx, struct PAC_SIGNATURE_DATA);
    120         srv_sig_wipe = TALLOC_ZERO_P(mem_ctx, struct PAC_SIGNATURE_DATA);
    121         if (!pac_data_raw || !pac_data || !kdc_sig_wipe || !srv_sig_wipe) {
    122                 return NT_STATUS_NO_MEMORY;
    123         }
    124 
    125         ndr_err = ndr_pull_struct_blob(pac_data_blob, pac_data, pac_data,
    126                        (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA);
    127         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    128                 status = ndr_map_error2ntstatus(ndr_err);
    129                 DEBUG(0,("can't parse the PAC: %s\n",
    130                         nt_errstr(status)));
    131                 return status;
    132         }
    133 
    134         if (pac_data->num_buffers < 4) {
    135                 /* we need logon_ingo, service_key and kdc_key */
    136                 DEBUG(0,("less than 4 PAC buffers\n"));
    137                 return NT_STATUS_INVALID_PARAMETER;
    138         }
    139 
    140         ndr_err = ndr_pull_struct_blob(
    141                                 pac_data_blob, pac_data_raw, pac_data_raw,
    142                                 (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA_RAW);
    143         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    144                 status = ndr_map_error2ntstatus(ndr_err);
    145                 DEBUG(0,("can't parse the PAC: %s\n",
    146                         nt_errstr(status)));
    147                 return status;
    148         }
    149 
    150         if (pac_data_raw->num_buffers < 4) {
    151                 /* we need logon_ingo, service_key and kdc_key */
    152                 DEBUG(0,("less than 4 PAC buffers\n"));
    153                 return NT_STATUS_INVALID_PARAMETER;
    154         }
    155 
    156         if (pac_data->num_buffers != pac_data_raw->num_buffers) {
    157                 /* we need logon_ingo, service_key and kdc_key */
    158                 DEBUG(0, ("misparse! PAC_DATA has %d buffers while "
    159                           "PAC_DATA_RAW has %d\n", pac_data->num_buffers,
    160                           pac_data_raw->num_buffers));
    161                 return NT_STATUS_INVALID_PARAMETER;
    162         }
    163 
    164         for (i=0; i < pac_data->num_buffers; i++) {
    165                 struct PAC_BUFFER *data_buf = &pac_data->buffers[i];
    166                 struct PAC_BUFFER_RAW *raw_buf = &pac_data_raw->buffers[i];
    167 
    168                 if (data_buf->type != raw_buf->type) {
    169                         DEBUG(0, ("misparse! PAC_DATA buffer %d has type "
    170                                   "%d while PAC_DATA_RAW has %d\n", i,
    171                                   data_buf->type, raw_buf->type));
    172                         return NT_STATUS_INVALID_PARAMETER;
    173                 }
    174                 switch (data_buf->type) {
    175                 case PAC_TYPE_LOGON_INFO:
    176                         if (!data_buf->info) {
    177                                 break;
    178                         }
    179                         logon_info = data_buf->info->logon_info.info;
    180                         break;
    181                 case PAC_TYPE_SRV_CHECKSUM:
    182                         if (!data_buf->info) {
    183                                 break;
    184                         }
    185                         srv_sig_ptr = &data_buf->info->srv_cksum;
    186                         srv_sig_blob = &raw_buf->info->remaining;
    187                         break;
    188                 case PAC_TYPE_KDC_CHECKSUM:
    189                         if (!data_buf->info) {
    190                                 break;
    191                         }
    192                         kdc_sig_ptr = &data_buf->info->kdc_cksum;
    193                         kdc_sig_blob = &raw_buf->info->remaining;
    194                         break;
    195                 case PAC_TYPE_LOGON_NAME:
    196                         logon_name = &data_buf->info->logon_name;
    197                         break;
    198                 default:
    199                         break;
    200                 }
    201         }
    202 
    203         if (!logon_info) {
    204                 DEBUG(0,("PAC no logon_info\n"));
    205                 return NT_STATUS_INVALID_PARAMETER;
    206         }
    207 
    208         if (!logon_name) {
    209                 DEBUG(0,("PAC no logon_name\n"));
    210                 return NT_STATUS_INVALID_PARAMETER;
    211         }
    212 
    213         if (!srv_sig_ptr || !srv_sig_blob) {
    214                 DEBUG(0,("PAC no srv_key\n"));
    215                 return NT_STATUS_INVALID_PARAMETER;
    216         }
    217 
    218         if (!kdc_sig_ptr || !kdc_sig_blob) {
    219                 DEBUG(0,("PAC no kdc_key\n"));
    220                 return NT_STATUS_INVALID_PARAMETER;
    221         }
    222 
    223         /* Find and zero out the signatures,
    224          * as required by the signing algorithm */
    225 
    226         /* We find the data blobs above,
    227          * now we parse them to get at the exact portion we should zero */
    228         ndr_err = ndr_pull_struct_blob(
    229                         kdc_sig_blob, kdc_sig_wipe, kdc_sig_wipe,
    230                         (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA);
    231         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    232                 status = ndr_map_error2ntstatus(ndr_err);
    233                 DEBUG(0,("can't parse the KDC signature: %s\n",
    234                         nt_errstr(status)));
    235                 return status;
    236         }
    237 
    238         ndr_err = ndr_pull_struct_blob(
    239                         srv_sig_blob, srv_sig_wipe, srv_sig_wipe,
    240                         (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA);
    241         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    242                 status = ndr_map_error2ntstatus(ndr_err);
    243                 DEBUG(0,("can't parse the SRV signature: %s\n",
    244                         nt_errstr(status)));
    245                 return status;
    246         }
    247 
    248         /* Now zero the decoded structure */
    249         memset(kdc_sig_wipe->signature.data,
    250                 '\0', kdc_sig_wipe->signature.length);
    251         memset(srv_sig_wipe->signature.data,
    252                 '\0', srv_sig_wipe->signature.length);
    253 
    254         /* and reencode, back into the same place it came from */
    255         ndr_err = ndr_push_struct_blob(
    256                         kdc_sig_blob, pac_data_raw, kdc_sig_wipe,
    257                         (ndr_push_flags_fn_t)ndr_push_PAC_SIGNATURE_DATA);
    258         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    259                 status = ndr_map_error2ntstatus(ndr_err);
    260                 DEBUG(0,("can't repack the KDC signature: %s\n",
    261                         nt_errstr(status)));
    262                 return status;
    263         }
    264         ndr_err = ndr_push_struct_blob(
    265                         srv_sig_blob, pac_data_raw, srv_sig_wipe,
    266                         (ndr_push_flags_fn_t)ndr_push_PAC_SIGNATURE_DATA);
    267         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    268                 status = ndr_map_error2ntstatus(ndr_err);
    269                 DEBUG(0,("can't repack the SRV signature: %s\n",
    270                         nt_errstr(status)));
    271                 return status;
    272         }
    273 
    274         /* push out the whole structure, but now with zero'ed signatures */
    275         ndr_err = ndr_push_struct_blob(
    276                         &modified_pac_blob, pac_data_raw, pac_data_raw,
    277                         (ndr_push_flags_fn_t)ndr_push_PAC_DATA_RAW);
    278         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    279                 status = ndr_map_error2ntstatus(ndr_err);
    280                 DEBUG(0,("can't repack the RAW PAC: %s\n",
    281                         nt_errstr(status)));
    282                 return status;
    283         }
    284 
    285         /* verify by service_key */
    286         ret = check_pac_checksum(mem_ctx,
    287                                  modified_pac_blob, srv_sig_ptr,
    288                                  context,
    289                                  service_keyblock);
    290         if (ret) {
    291                 DEBUG(1, ("PAC Decode: Failed to verify the service "
    292                           "signature: %s\n", error_message(ret)));
    293                 return NT_STATUS_ACCESS_DENIED;
    294         }
    295 
    296         /* Convert to NT time, so as not to loose accuracy in comparison */
    297         unix_to_nt_time(&tgs_authtime_nttime, tgs_authtime);
    298 
    299         if (tgs_authtime_nttime != logon_name->logon_time) {
    300                 DEBUG(2, ("PAC Decode: "
    301                           "Logon time mismatch between ticket and PAC!\n"));
    302                 DEBUG(2, ("PAC Decode: PAC: %s\n",
    303                           nt_time_string(mem_ctx, logon_name->logon_time)));
    304                 DEBUG(2, ("PAC Decode: Ticket: %s\n",
    305                           nt_time_string(mem_ctx, tgs_authtime_nttime)));
    306                 return NT_STATUS_ACCESS_DENIED;
    307         }
    308 
    309         ret = smb_krb5_parse_name_norealm(context,
    310                                           logon_name->account_name,
    311                                           &client_principal_pac);
    312         if (ret) {
    313                 DEBUG(2, ("Could not parse name from PAC: [%s]:%s\n",
    314                           logon_name->account_name, error_message(ret)));
    315                 return NT_STATUS_INVALID_PARAMETER;
    316         }
    317 
    318         bool_ret = smb_krb5_principal_compare_any_realm(context,
    319                                                         client_principal,
    320                                                         client_principal_pac);
    321 
    322         krb5_free_principal(context, client_principal_pac);
    323 
    324         if (!bool_ret) {
    325                 DEBUG(2, ("Name in PAC [%s] does not match principal name "
    326                           "in ticket\n", logon_name->account_name));
    327                 return NT_STATUS_ACCESS_DENIED;
    328         }
    329 
    330         DEBUG(3,("Found account name from PAC: %s [%s]\n",
    331                  logon_info->info3.base.account_name.string,
    332                  logon_info->info3.base.full_name.string));
    333 
    334         DEBUG(10,("Successfully validated Kerberos PAC\n"));
    335 
    336         if (DEBUGLEVEL >= 10) {
    337                 const char *s;
    338                 s = NDR_PRINT_STRUCT_STRING(mem_ctx, PAC_DATA, pac_data);
    339                 if (s) {
    340                         DEBUGADD(10,("%s\n", s));
    341                 }
    342         }
    343 
    344         *pac_data_out = pac_data;
    345 
    346         return NT_STATUS_OK;
    347 }
    348 
    349 /****************************************************************
    350 Given a username, password and other details, return the
    351 PAC_LOGON_INFO (the structure containing the important user
    352 information such as groups).
    353 ****************************************************************/
    354 
     106/*
     107 * Given the username/password, do a kinit, store the ticket in
     108 * cache_name if specified, and return the PAC_LOGON_INFO (the
     109 * structure containing the important user information such as
     110 * groups).
     111 */
    355112NTSTATUS kerberos_return_pac(TALLOC_CTX *mem_ctx,
    356113                             const char *name,
     
    364121                             time_t renewable_time,
    365122                             const char *impersonate_princ_s,
    366                              struct PAC_LOGON_INFO **logon_info)
     123                             const char *local_service,
     124                             struct PAC_DATA_CTR **_pac_data_ctr)
    367125{
    368126        krb5_error_code ret;
    369127        NTSTATUS status = NT_STATUS_INVALID_PARAMETER;
    370         DATA_BLOB tkt, ap_rep, sesskey1, sesskey2;
    371         char *client_princ_out = NULL;
     128        DATA_BLOB tkt, tkt_wrapped, ap_rep, sesskey1;
    372129        const char *auth_princ = NULL;
    373         const char *local_service = NULL;
    374130        const char *cc = "MEMORY:kerberos_return_pac";
     131        struct auth_session_info *session_info;
     132        struct gensec_security *gensec_server_context;
     133        const struct gensec_security_ops **backends;
     134        struct gensec_settings *gensec_settings;
     135        size_t idx = 0;
     136        struct auth4_context *auth_context;
     137        struct loadparm_context *lp_ctx;
     138        struct PAC_DATA_CTR *pac_data_ctr = NULL;
     139
     140        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     141        NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
    375142
    376143        ZERO_STRUCT(tkt);
    377144        ZERO_STRUCT(ap_rep);
    378145        ZERO_STRUCT(sesskey1);
    379         ZERO_STRUCT(sesskey2);
    380146
    381147        if (!name || !pass) {
     
    394160        }
    395161        NT_STATUS_HAVE_NO_MEMORY(auth_princ);
    396 
    397         local_service = talloc_asprintf(mem_ctx, "%s$@%s",
    398                                         global_myname(), lp_realm());
    399         NT_STATUS_HAVE_NO_MEMORY(local_service);
    400162
    401163        ret = kerberos_kinit_password_ext(auth_princ,
     
    455217                goto out;
    456218        }
    457         status = ads_verify_ticket(mem_ctx,
    458                                    lp_realm(),
    459                                    time_offset,
    460                                    &tkt,
    461                                    &client_princ_out,
    462                                    logon_info,
    463                                    &ap_rep,
    464                                    &sesskey2,
    465                                    False);
     219
     220        /* wrap that up in a nice GSS-API wrapping */
     221        tkt_wrapped = spnego_gen_krb5_wrap(tmp_ctx, tkt, TOK_ID_KRB_AP_REQ);
     222        if (tkt_wrapped.data == NULL) {
     223                status = NT_STATUS_NO_MEMORY;
     224                goto out;
     225        }
     226
     227        auth_context = talloc_zero(tmp_ctx, struct auth4_context);
     228        if (auth_context == NULL) {
     229                status = NT_STATUS_NO_MEMORY;
     230                goto out;
     231        }
     232        auth_context->generate_session_info_pac = kerberos_fetch_pac;
     233
     234        lp_ctx = loadparm_init_s3(tmp_ctx, loadparm_s3_helpers());
     235        if (lp_ctx == NULL) {
     236                status = NT_STATUS_INVALID_SERVER_STATE;
     237                DEBUG(10, ("loadparm_init_s3 failed\n"));
     238                goto out;
     239        }
     240
     241        gensec_settings = lpcfg_gensec_settings(tmp_ctx, lp_ctx);
     242        if (gensec_settings == NULL) {
     243                status = NT_STATUS_NO_MEMORY;
     244                DEBUG(10, ("lpcfg_gensec_settings failed\n"));
     245                goto out;
     246        }
     247
     248        backends = talloc_zero_array(gensec_settings,
     249                                     const struct gensec_security_ops *, 2);
     250        if (backends == NULL) {
     251                status = NT_STATUS_NO_MEMORY;
     252                goto out;
     253        }
     254        gensec_settings->backends = backends;
     255
     256        gensec_init();
     257
     258        backends[idx++] = &gensec_gse_krb5_security_ops;
     259
     260        status = gensec_server_start(tmp_ctx, gensec_settings,
     261                                        auth_context, &gensec_server_context);
     262
    466263        if (!NT_STATUS_IS_OK(status)) {
    467                 DEBUG(1,("ads_verify_ticket failed: %s\n",
    468                         nt_errstr(status)));
    469                 goto out;
    470         }
    471 
    472         if (!*logon_info) {
     264                DEBUG(1, (__location__ "Failed to start server-side GENSEC to validate a Kerberos ticket: %s\n", nt_errstr(status)));
     265                goto out;
     266        }
     267
     268        talloc_unlink(tmp_ctx, lp_ctx);
     269        talloc_unlink(tmp_ctx, gensec_settings);
     270        talloc_unlink(tmp_ctx, auth_context);
     271
     272        status = gensec_start_mech_by_oid(gensec_server_context, GENSEC_OID_KERBEROS5);
     273        if (!NT_STATUS_IS_OK(status)) {
     274                DEBUG(1, (__location__ "Failed to start server-side GENSEC krb5 to validate a Kerberos ticket: %s\n", nt_errstr(status)));
     275                goto out;
     276        }
     277
     278        /* Do a client-server update dance */
     279        status = gensec_update(gensec_server_context, tmp_ctx, tkt_wrapped, &ap_rep);
     280        if (!NT_STATUS_IS_OK(status)) {
     281                DEBUG(1, ("gensec_update() failed: %s\n", nt_errstr(status)));
     282                goto out;
     283        }
     284
     285        /* Now return the PAC information to the callers.  We ingore
     286         * the session_info and instead pick out the PAC via the
     287         * private_data on the auth_context */
     288        status = gensec_session_info(gensec_server_context, tmp_ctx, &session_info);
     289        if (!NT_STATUS_IS_OK(status)) {
     290                DEBUG(1, ("Unable to obtain PAC via gensec_session_info\n"));
     291                goto out;
     292        }
     293
     294        pac_data_ctr = talloc_get_type_abort(gensec_server_context->auth_context->private_data,
     295                                             struct PAC_DATA_CTR);
     296        if (pac_data_ctr == NULL) {
    473297                DEBUG(1,("no PAC\n"));
    474298                status = NT_STATUS_INVALID_PARAMETER;
     
    476300        }
    477301
     302        *_pac_data_ctr = talloc_move(mem_ctx, &pac_data_ctr);
     303
    478304out:
     305        talloc_free(tmp_ctx);
    479306        if (cc != cache_name) {
    480307                ads_kdestroy(cc);
     
    484311        data_blob_free(&ap_rep);
    485312        data_blob_free(&sesskey1);
    486         data_blob_free(&sesskey2);
    487 
    488         TALLOC_FREE(client_princ_out);
    489313
    490314        return status;
Note: See TracChangeset for help on using the changeset viewer.