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

Samba Server: update vendor to version 4.4.3

Location:
vendor/current/source4/auth/gensec
Files:
2 added
8 deleted
6 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source4/auth/gensec/gensec_gssapi.c

    r740 r988  
    2525#include "lib/events/events.h"
    2626#include "system/kerberos.h"
     27#include "system/gssapi.h"
    2728#include "auth/kerberos/kerberos.h"
    2829#include "librpc/gen_ndr/krb5pac.h"
     
    3031#include <ldb.h>
    3132#include "auth/auth_sam.h"
    32 #include "librpc/rpc/dcerpc.h"
     33#include "librpc/gen_ndr/dcerpc.h"
    3334#include "auth/credentials/credentials.h"
    3435#include "auth/credentials/credentials_krb5.h"
    3536#include "auth/gensec/gensec.h"
     37#include "auth/gensec/gensec_internal.h"
    3638#include "auth/gensec/gensec_proto.h"
     39#include "auth/gensec/gensec_toplevel_proto.h"
    3740#include "param/param.h"
    3841#include "auth/session_proto.h"
    39 #include <gssapi/gssapi.h>
    40 #include <gssapi/gssapi_krb5.h>
    41 #include <gssapi/gssapi_spnego.h>
    42 #include "auth/gensec/gensec_gssapi.h"
     42#include "gensec_gssapi.h"
    4343#include "lib/util/util_net.h"
     44#include "auth/kerberos/pac_utils.h"
     45#include "auth/kerberos/gssapi_helper.h"
     46
     47#ifndef gss_mech_spnego
     48gss_OID_desc spnego_mech_oid_desc =
     49                { 6, discard_const_p(void, "\x2b\x06\x01\x05\x05\x02") };
     50#define gss_mech_spnego (&spnego_mech_oid_desc)
     51#endif
     52
     53_PUBLIC_ NTSTATUS gensec_gssapi_init(void);
    4454
    4555static size_t gensec_gssapi_max_input_size(struct gensec_security *gensec_security);
    4656static size_t gensec_gssapi_max_wrapped_size(struct gensec_security *gensec_security);
    47 
    48 static char *gssapi_error_string(TALLOC_CTX *mem_ctx,
    49                                  OM_uint32 maj_stat, OM_uint32 min_stat,
    50                                  const gss_OID mech)
    51 {
    52         OM_uint32 disp_min_stat, disp_maj_stat;
    53         gss_buffer_desc maj_error_message;
    54         gss_buffer_desc min_error_message;
    55         char *maj_error_string, *min_error_string;
    56         OM_uint32 msg_ctx = 0;
    57 
    58         char *ret;
    59 
    60         maj_error_message.value = NULL;
    61         min_error_message.value = NULL;
    62         maj_error_message.length = 0;
    63         min_error_message.length = 0;
    64        
    65         disp_maj_stat = gss_display_status(&disp_min_stat, maj_stat, GSS_C_GSS_CODE,
    66                            mech, &msg_ctx, &maj_error_message);
    67         disp_maj_stat = gss_display_status(&disp_min_stat, min_stat, GSS_C_MECH_CODE,
    68                            mech, &msg_ctx, &min_error_message);
    69        
    70         maj_error_string = talloc_strndup(mem_ctx, (char *)maj_error_message.value, maj_error_message.length);
    71 
    72         min_error_string = talloc_strndup(mem_ctx, (char *)min_error_message.value, min_error_message.length);
    73 
    74         ret = talloc_asprintf(mem_ctx, "%s: %s", maj_error_string, min_error_string);
    75 
    76         talloc_free(maj_error_string);
    77         talloc_free(min_error_string);
    78 
    79         gss_release_buffer(&disp_min_stat, &maj_error_message);
    80         gss_release_buffer(&disp_min_stat, &min_error_message);
    81 
    82         return ret;
    83 }
    84 
     57static size_t gensec_gssapi_sig_size(struct gensec_security *gensec_security, size_t data_size);
    8558
    8659static int gensec_gssapi_destructor(struct gensec_gssapi_state *gensec_gssapi_state)
    8760{
    88         OM_uint32 maj_stat, min_stat;
    89        
     61        OM_uint32 min_stat;
     62
    9063        if (gensec_gssapi_state->delegated_cred_handle != GSS_C_NO_CREDENTIAL) {
    91                 maj_stat = gss_release_cred(&min_stat,
    92                                             &gensec_gssapi_state->delegated_cred_handle);
     64                gss_release_cred(&min_stat,
     65                                &gensec_gssapi_state->delegated_cred_handle);
    9366        }
    9467
    9568        if (gensec_gssapi_state->gssapi_context != GSS_C_NO_CONTEXT) {
    96                 maj_stat = gss_delete_sec_context (&min_stat,
    97                                                    &gensec_gssapi_state->gssapi_context,
    98                                                    GSS_C_NO_BUFFER);
     69                gss_delete_sec_context(&min_stat,
     70                                       &gensec_gssapi_state->gssapi_context,
     71                                       GSS_C_NO_BUFFER);
    9972        }
    10073
    10174        if (gensec_gssapi_state->server_name != GSS_C_NO_NAME) {
    102                 maj_stat = gss_release_name(&min_stat, &gensec_gssapi_state->server_name);
     75                gss_release_name(&min_stat,
     76                                 &gensec_gssapi_state->server_name);
    10377        }
    10478        if (gensec_gssapi_state->client_name != GSS_C_NO_NAME) {
    105                 maj_stat = gss_release_name(&min_stat, &gensec_gssapi_state->client_name);
    106         }
    107 
    108         if (gensec_gssapi_state->lucid) {
    109                 gss_krb5_free_lucid_sec_context(&min_stat, gensec_gssapi_state->lucid);
     79                gss_release_name(&min_stat,
     80                                 &gensec_gssapi_state->client_name);
    11081        }
    11182
    11283        return 0;
    113 }
    114 
    115 static NTSTATUS gensec_gssapi_init_lucid(struct gensec_gssapi_state *gensec_gssapi_state)
    116 {
    117         OM_uint32 maj_stat, min_stat;
    118 
    119         if (gensec_gssapi_state->lucid) {
    120                 return NT_STATUS_OK;
    121         }
    122 
    123         maj_stat = gss_krb5_export_lucid_sec_context(&min_stat,
    124                                                      &gensec_gssapi_state->gssapi_context,
    125                                                      1,
    126                                                      (void **)&gensec_gssapi_state->lucid);
    127         if (maj_stat != GSS_S_COMPLETE) {
    128                 DEBUG(0,("gensec_gssapi_init_lucid: %s\n",
    129                         gssapi_error_string(gensec_gssapi_state,
    130                                             maj_stat, min_stat,
    131                                             gensec_gssapi_state->gss_oid)));
    132                 return NT_STATUS_INTERNAL_ERROR;
    133         }
    134 
    135         if (gensec_gssapi_state->lucid->version != 1) {
    136                 DEBUG(0,("gensec_gssapi_init_lucid: lucid version[%d] != 1\n",
    137                         gensec_gssapi_state->lucid->version));
    138                 gss_krb5_free_lucid_sec_context(&min_stat, gensec_gssapi_state->lucid);
    139                 gensec_gssapi_state->lucid = NULL;
    140                 return NT_STATUS_INTERNAL_ERROR;
    141         }
    142 
    143         return NT_STATUS_OK;
    14484}
    14585
     
    14888        struct gensec_gssapi_state *gensec_gssapi_state;
    14989        krb5_error_code ret;
     90#ifdef SAMBA4_USES_HEIMDAL
    15091        const char *realm;
     92#endif
    15193
    15294        gensec_gssapi_state = talloc_zero(gensec_security, struct gensec_gssapi_state);
     
    165107        gensec_gssapi_state->client_name = GSS_C_NO_NAME;
    166108       
    167         gensec_gssapi_state->want_flags = 0;
     109        gensec_gssapi_state->gss_want_flags = 0;
     110        gensec_gssapi_state->expire_time = GENSEC_EXPIRE_TIME_INFINITY;
    168111
    169112        if (gensec_setting_bool(gensec_security->settings, "gensec_gssapi", "delegation_by_kdc_policy", true)) {
    170                 gensec_gssapi_state->want_flags |= GSS_C_DELEG_POLICY_FLAG;
     113                gensec_gssapi_state->gss_want_flags |= GSS_C_DELEG_POLICY_FLAG;
    171114        }
    172115        if (gensec_setting_bool(gensec_security->settings, "gensec_gssapi", "mutual", true)) {
    173                 gensec_gssapi_state->want_flags |= GSS_C_MUTUAL_FLAG;
     116                gensec_gssapi_state->gss_want_flags |= GSS_C_MUTUAL_FLAG;
    174117        }
    175118        if (gensec_setting_bool(gensec_security->settings, "gensec_gssapi", "delegation", true)) {
    176                 gensec_gssapi_state->want_flags |= GSS_C_DELEG_FLAG;
     119                gensec_gssapi_state->gss_want_flags |= GSS_C_DELEG_FLAG;
    177120        }
    178121        if (gensec_setting_bool(gensec_security->settings, "gensec_gssapi", "replay", true)) {
    179                 gensec_gssapi_state->want_flags |= GSS_C_REPLAY_FLAG;
     122                gensec_gssapi_state->gss_want_flags |= GSS_C_REPLAY_FLAG;
    180123        }
    181124        if (gensec_setting_bool(gensec_security->settings, "gensec_gssapi", "sequence", true)) {
    182                 gensec_gssapi_state->want_flags |= GSS_C_SEQUENCE_FLAG;
     125                gensec_gssapi_state->gss_want_flags |= GSS_C_SEQUENCE_FLAG;
    183126        }
    184127
    185128        if (gensec_security->want_features & GENSEC_FEATURE_SIGN) {
    186                 gensec_gssapi_state->want_flags |= GSS_C_INTEG_FLAG;
     129                gensec_gssapi_state->gss_want_flags |= GSS_C_INTEG_FLAG;
    187130        }
    188131        if (gensec_security->want_features & GENSEC_FEATURE_SEAL) {
    189                 gensec_gssapi_state->want_flags |= GSS_C_CONF_FLAG;
     132                gensec_gssapi_state->gss_want_flags |= GSS_C_INTEG_FLAG;
     133                gensec_gssapi_state->gss_want_flags |= GSS_C_CONF_FLAG;
    190134        }
    191135        if (gensec_security->want_features & GENSEC_FEATURE_DCE_STYLE) {
    192                 gensec_gssapi_state->want_flags |= GSS_C_DCE_STYLE;
    193         }
    194 
    195         gensec_gssapi_state->got_flags = 0;
     136                gensec_gssapi_state->gss_want_flags |= GSS_C_DCE_STYLE;
     137        }
     138
     139        gensec_gssapi_state->gss_got_flags = 0;
    196140
    197141        switch (gensec_security->ops->auth_type) {
     
    201145        case DCERPC_AUTH_TYPE_KRB5:
    202146        default:
    203                 gensec_gssapi_state->gss_oid = gss_mech_krb5;
     147                gensec_gssapi_state->gss_oid =
     148                        discard_const_p(void, gss_mech_krb5);
    204149                break;
    205150        }
    206151
    207         gensec_gssapi_state->session_key = data_blob(NULL, 0);
    208         gensec_gssapi_state->pac = data_blob(NULL, 0);
    209 
    210152        ret = smb_krb5_init_context(gensec_gssapi_state,
    211                                     NULL,
    212153                                    gensec_security->settings->lp_ctx,
    213154                                    &gensec_gssapi_state->smb_krb5_context);
    214155        if (ret) {
    215                 DEBUG(1,("gensec_krb5_start: krb5_init_context failed (%s)\n",
     156                DEBUG(1,("gensec_gssapi_start: smb_krb5_init_context failed (%s)\n",
    216157                         error_message(ret)));
    217158                talloc_free(gensec_gssapi_state);
     
    221162        gensec_gssapi_state->client_cred = NULL;
    222163        gensec_gssapi_state->server_cred = NULL;
    223 
    224         gensec_gssapi_state->lucid = NULL;
    225164
    226165        gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL;
     
    237176        talloc_set_destructor(gensec_gssapi_state, gensec_gssapi_destructor);
    238177
     178#ifdef SAMBA4_USES_HEIMDAL
    239179        realm = lpcfg_realm(gensec_security->settings->lp_ctx);
    240180        if (realm != NULL) {
    241181                ret = gsskrb5_set_default_realm(realm);
    242182                if (ret) {
    243                         DEBUG(1,("gensec_krb5_start: gsskrb5_set_default_realm failed\n"));
     183                        DEBUG(1,("gensec_gssapi_start: gsskrb5_set_default_realm failed\n"));
    244184                        talloc_free(gensec_gssapi_state);
    245185                        return NT_STATUS_INTERNAL_ERROR;
     
    250190        ret = gsskrb5_set_dns_canonicalize(gensec_setting_bool(gensec_security->settings, "krb5", "set_dns_canonicalize", false));
    251191        if (ret) {
    252                 DEBUG(1,("gensec_krb5_start: gsskrb5_set_dns_canonicalize failed\n"));
     192                DEBUG(1,("gensec_gssapi_start: gsskrb5_set_dns_canonicalize failed\n"));
    253193                talloc_free(gensec_gssapi_state);
    254194                return NT_STATUS_INTERNAL_ERROR;
    255195        }
    256 
     196#endif
    257197        return NT_STATUS_OK;
    258198}
     
    306246}
    307247
    308 static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_security)
     248static NTSTATUS gensec_gssapi_client_creds(struct gensec_security *gensec_security,
     249                                           struct tevent_context *ev)
    309250{
    310251        struct gensec_gssapi_state *gensec_gssapi_state;
     252        struct gssapi_creds_container *gcc;
    311253        struct cli_credentials *creds = gensec_get_credentials(gensec_security);
    312         krb5_error_code ret;
    313         NTSTATUS nt_status;
    314         gss_buffer_desc name_token;
    315         gss_OID name_type;
    316         OM_uint32 maj_stat, min_stat;
    317         const char *hostname = gensec_get_target_hostname(gensec_security);
    318         struct gssapi_creds_container *gcc;
    319254        const char *error_string;
    320 
    321         if (!hostname) {
    322                 DEBUG(1, ("Could not determine hostname for target computer, cannot use kerberos\n"));
    323                 return NT_STATUS_INVALID_PARAMETER;
    324         }
    325         if (is_ipaddress(hostname)) {
    326                 DEBUG(2, ("Cannot do GSSAPI to an IP address\n"));
    327                 return NT_STATUS_INVALID_PARAMETER;
    328         }
    329         if (strcmp(hostname, "localhost") == 0) {
    330                 DEBUG(2, ("GSSAPI to 'localhost' does not make sense\n"));
    331                 return NT_STATUS_INVALID_PARAMETER;
    332         }
    333 
    334         nt_status = gensec_gssapi_start(gensec_security);
    335         if (!NT_STATUS_IS_OK(nt_status)) {
    336                 return nt_status;
    337         }
     255        int ret;
    338256
    339257        gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
    340258
    341         gensec_gssapi_state->target_principal = gensec_get_target_principal(gensec_security);
    342         if (gensec_gssapi_state->target_principal) {
    343                 name_type = GSS_C_NULL_OID;
    344         } else {
    345                 gensec_gssapi_state->target_principal = talloc_asprintf(gensec_gssapi_state, "%s/%s@%s",
    346                                             gensec_get_target_service(gensec_security),
    347                                             hostname, lpcfg_realm(gensec_security->settings->lp_ctx));
    348 
    349                 name_type = GSS_C_NT_USER_NAME;
    350         }
    351         name_token.value  = discard_const_p(uint8_t, gensec_gssapi_state->target_principal);
    352         name_token.length = strlen(gensec_gssapi_state->target_principal);
    353 
    354 
    355         maj_stat = gss_import_name (&min_stat,
    356                                     &name_token,
    357                                     name_type,
    358                                     &gensec_gssapi_state->server_name);
    359         if (maj_stat) {
    360                 DEBUG(2, ("GSS Import name of %s failed: %s\n",
    361                           (char *)name_token.value,
    362                           gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
    363                 return NT_STATUS_INVALID_PARAMETER;
    364         }
    365 
    366         ret = cli_credentials_get_client_gss_creds(creds,
    367                                                    gensec_security->event_ctx,
     259        /* Only run this the first time the update() call is made */
     260        if (gensec_gssapi_state->client_cred) {
     261                return NT_STATUS_OK;
     262        }
     263
     264        ret = cli_credentials_get_client_gss_creds(creds,
     265                                                   ev,
    368266                                                   gensec_security->settings->lp_ctx, &gcc, &error_string);
    369267        switch (ret) {
    370268        case 0:
    371269                break;
     270        case EINVAL:
     271                DEBUG(3, ("Cannot obtain client GSS credentials we need to contact %s : %s\n", gensec_gssapi_state->target_principal, error_string));
     272                return NT_STATUS_INVALID_PARAMETER;
    372273        case KRB5KDC_ERR_PREAUTH_FAILED:
    373274        case KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN:
     275        case KRB5KRB_AP_ERR_BAD_INTEGRITY:
    374276                DEBUG(1, ("Wrong username or password: %s\n", error_string));
    375277                return NT_STATUS_LOGON_FAILURE;
     278        case KRB5KDC_ERR_CLIENT_REVOKED:
     279                DEBUG(1, ("Account locked out: %s\n", error_string));
     280                return NT_STATUS_ACCOUNT_LOCKED_OUT;
     281        case KRB5_REALM_UNKNOWN:
    376282        case KRB5_KDC_UNREACH:
    377283                DEBUG(3, ("Cannot reach a KDC we require to contact %s : %s\n", gensec_gssapi_state->target_principal, error_string));
     
    390296                return NT_STATUS_NO_MEMORY;
    391297        }
    392        
     298
     299        return NT_STATUS_OK;
     300}
     301
     302static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_security)
     303{
     304        struct gensec_gssapi_state *gensec_gssapi_state;
     305        struct cli_credentials *creds = gensec_get_credentials(gensec_security);
     306        NTSTATUS nt_status;
     307        gss_buffer_desc name_token;
     308        gss_OID name_type;
     309        OM_uint32 maj_stat, min_stat;
     310        const char *hostname = gensec_get_target_hostname(gensec_security);
     311
     312        if (!hostname) {
     313                DEBUG(3, ("No hostname for target computer passed in, cannot use kerberos for this connection\n"));
     314                return NT_STATUS_INVALID_PARAMETER;
     315        }
     316        if (is_ipaddress(hostname)) {
     317                DEBUG(2, ("Cannot do GSSAPI to an IP address\n"));
     318                return NT_STATUS_INVALID_PARAMETER;
     319        }
     320        if (strcmp(hostname, "localhost") == 0) {
     321                DEBUG(2, ("GSSAPI to 'localhost' does not make sense\n"));
     322                return NT_STATUS_INVALID_PARAMETER;
     323        }
     324
     325        nt_status = gensec_gssapi_start(gensec_security);
     326        if (!NT_STATUS_IS_OK(nt_status)) {
     327                return nt_status;
     328        }
     329
     330        gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
     331
     332        if (cli_credentials_get_impersonate_principal(creds)) {
     333                gensec_gssapi_state->gss_want_flags &= ~(GSS_C_DELEG_FLAG|GSS_C_DELEG_POLICY_FLAG);
     334        }
     335
     336        gensec_gssapi_state->target_principal = gensec_get_target_principal(gensec_security);
     337        if (gensec_gssapi_state->target_principal) {
     338                name_type = GSS_C_NULL_OID;
     339        } else {
     340                gensec_gssapi_state->target_principal = talloc_asprintf(gensec_gssapi_state, "%s/%s@%s",
     341                                            gensec_get_target_service(gensec_security),
     342                                            hostname, lpcfg_realm(gensec_security->settings->lp_ctx));
     343
     344                name_type = GSS_C_NT_USER_NAME;
     345        }
     346        name_token.value  = discard_const_p(uint8_t, gensec_gssapi_state->target_principal);
     347        name_token.length = strlen(gensec_gssapi_state->target_principal);
     348
     349
     350        maj_stat = gss_import_name (&min_stat,
     351                                    &name_token,
     352                                    name_type,
     353                                    &gensec_gssapi_state->server_name);
     354        if (maj_stat) {
     355                DEBUG(2, ("GSS Import name of %s failed: %s\n",
     356                          (char *)name_token.value,
     357                          gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
     358                return NT_STATUS_INVALID_PARAMETER;
     359        }
     360
    393361        return NT_STATUS_OK;
    394362}
     
    405373        }
    406374        return nt_status;
    407 }
    408 
    409 
    410 /**
    411  * Check if the packet is one for this mechansim
    412  *
    413  * @param gensec_security GENSEC state
    414  * @param in The request, as a DATA_BLOB
    415  * @return Error, INVALID_PARAMETER if it's not a packet for us
    416  *                or NT_STATUS_OK if the packet is ok.
    417  */
    418 
    419 static NTSTATUS gensec_gssapi_magic(struct gensec_security *gensec_security,
    420                                     const DATA_BLOB *in)
    421 {
    422         if (gensec_gssapi_check_oid(in, GENSEC_OID_KERBEROS5)) {
    423                 return NT_STATUS_OK;
    424         } else {
    425                 return NT_STATUS_INVALID_PARAMETER;
    426         }
    427375}
    428376
     
    440388
    441389static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
    442                                    TALLOC_CTX *out_mem_ctx,
    443                                    const DATA_BLOB in, DATA_BLOB *out)
     390                                     TALLOC_CTX *out_mem_ctx,
     391                                     struct tevent_context *ev,
     392                                     const DATA_BLOB in, DATA_BLOB *out)
    444393{
    445394        struct gensec_gssapi_state *gensec_gssapi_state
     
    448397        OM_uint32 maj_stat, min_stat;
    449398        OM_uint32 min_stat2;
    450         gss_buffer_desc input_token, output_token;
     399        gss_buffer_desc input_token = { 0, NULL };
     400        gss_buffer_desc output_token = { 0, NULL };
     401
    451402        gss_OID gss_oid_p = NULL;
     403        OM_uint32 time_req = 0;
     404        OM_uint32 time_rec = 0;
     405        struct timeval tv;
     406
     407        time_req = gensec_setting_int(gensec_security->settings,
     408                                      "gensec_gssapi", "requested_life_time",
     409                                      time_req);
     410
    452411        input_token.length = in.length;
    453412        input_token.value = in.data;
     
    459418                case GENSEC_CLIENT:
    460419                {
     420#ifdef SAMBA4_USES_HEIMDAL
    461421                        struct gsskrb5_send_to_kdc send_to_kdc;
    462422                        krb5_error_code ret;
     423#endif
     424
     425                        nt_status = gensec_gssapi_client_creds(gensec_security, ev);
     426                        if (!NT_STATUS_IS_OK(nt_status)) {
     427                                return nt_status;
     428                        }
     429
     430#ifdef SAMBA4_USES_HEIMDAL
    463431                        send_to_kdc.func = smb_krb5_send_and_recv_func;
    464                         send_to_kdc.ptr = gensec_security->event_ctx;
     432                        send_to_kdc.ptr = ev;
    465433
    466434                        min_stat = gsskrb5_set_send_to_kdc(&send_to_kdc);
    467435                        if (min_stat) {
    468                                 DEBUG(1,("gensec_krb5_start: gsskrb5_set_send_to_kdc failed\n"));
     436                                DEBUG(1,("gensec_gssapi_update: gsskrb5_set_send_to_kdc failed\n"));
    469437                                return NT_STATUS_INTERNAL_ERROR;
    470438                        }
    471 
     439#endif
    472440                        maj_stat = gss_init_sec_context(&min_stat,
    473441                                                        gensec_gssapi_state->client_cred->creds,
     
    475443                                                        gensec_gssapi_state->server_name,
    476444                                                        gensec_gssapi_state->gss_oid,
    477                                                         gensec_gssapi_state->want_flags,
    478                                                         0,
     445                                                        gensec_gssapi_state->gss_want_flags,
     446                                                        time_req,
    479447                                                        gensec_gssapi_state->input_chan_bindings,
    480448                                                        &input_token,
    481449                                                        &gss_oid_p,
    482450                                                        &output_token,
    483                                                         &gensec_gssapi_state->got_flags, /* ret flags */
    484                                                         NULL);
     451                                                        &gensec_gssapi_state->gss_got_flags, /* ret flags */
     452                                                        &time_rec);
    485453                        if (gss_oid_p) {
    486454                                gensec_gssapi_state->gss_oid = gss_oid_p;
    487455                        }
    488456
     457#ifdef SAMBA4_USES_HEIMDAL
    489458                        send_to_kdc.func = smb_krb5_send_and_recv_func;
    490459                        send_to_kdc.ptr = NULL;
     
    492461                        ret = gsskrb5_set_send_to_kdc(&send_to_kdc);
    493462                        if (ret) {
    494                                 DEBUG(1,("gensec_krb5_start: gsskrb5_set_send_to_kdc failed\n"));
     463                                DEBUG(1,("gensec_gssapi_update: gsskrb5_set_send_to_kdc failed\n"));
    495464                                return NT_STATUS_INTERNAL_ERROR;
    496465                        }
    497 
     466#endif
    498467                        break;
    499468                }
     
    508477                                                          &gss_oid_p,
    509478                                                          &output_token,
    510                                                           &gensec_gssapi_state->got_flags,
    511                                                           NULL,
     479                                                          &gensec_gssapi_state->gss_got_flags,
     480                                                          &time_rec,
    512481                                                          &gensec_gssapi_state->delegated_cred_handle);
    513482                        if (gss_oid_p) {
     
    527496                        gss_release_buffer(&min_stat2, &output_token);
    528497                       
    529                         if (gensec_gssapi_state->got_flags & GSS_C_DELEG_FLAG) {
     498                        if (gensec_gssapi_state->gss_got_flags & GSS_C_DELEG_FLAG &&
     499                            gensec_gssapi_state->delegated_cred_handle != GSS_C_NO_CREDENTIAL) {
    530500                                DEBUG(5, ("gensec_gssapi: credentials were delegated\n"));
    531501                        } else {
    532502                                DEBUG(5, ("gensec_gssapi: NO credentials were delegated\n"));
    533503                        }
     504
     505                        tv = timeval_current_ofs(time_rec, 0);
     506                        gensec_gssapi_state->expire_time = timeval_to_nttime(&tv);
    534507
    535508                        /* We may have been invoked as SASL, so there
     
    556529                       
    557530                        return NT_STATUS_MORE_PROCESSING_REQUIRED;
    558                 } else if (gss_oid_equal(gensec_gssapi_state->gss_oid, gss_mech_krb5)) {
     531                } else if (maj_stat == GSS_S_CONTEXT_EXPIRED) {
     532                        gss_cred_id_t creds = NULL;
     533                        gss_name_t name;
     534                        gss_buffer_desc buffer;
     535                        OM_uint32 lifetime = 0;
     536                        gss_cred_usage_t usage;
     537                        const char *role = NULL;
     538                        DEBUG(0, ("GSS %s Update(krb5)(%d) Update failed, credentials expired during GSSAPI handshake!\n",
     539                                  role,
     540                                  gensec_gssapi_state->gss_exchange_count));
     541
     542                       
     543                        switch (gensec_security->gensec_role) {
     544                        case GENSEC_CLIENT:
     545                                creds = gensec_gssapi_state->client_cred->creds;
     546                                role = "client";
     547                                break;
     548                        case GENSEC_SERVER:
     549                                creds = gensec_gssapi_state->server_cred->creds;
     550                                role = "server";
     551                                break;
     552                        }
     553
     554                        maj_stat = gss_inquire_cred(&min_stat,
     555                                                    creds,
     556                                                    &name, &lifetime, &usage, NULL);
     557
     558                        if (maj_stat == GSS_S_COMPLETE) {
     559                                const char *usage_string = NULL;
     560                                switch (usage) {
     561                                case GSS_C_BOTH:
     562                                        usage_string = "GSS_C_BOTH";
     563                                        break;
     564                                case GSS_C_ACCEPT:
     565                                        usage_string = "GSS_C_ACCEPT";
     566                                        break;
     567                                case GSS_C_INITIATE:
     568                                        usage_string = "GSS_C_INITIATE";
     569                                        break;
     570                                }
     571                                maj_stat = gss_display_name(&min_stat, name, &buffer, NULL);
     572                                if (maj_stat) {
     573                                        buffer.value = NULL;
     574                                        buffer.length = 0;
     575                                }
     576                                if (lifetime > 0) {
     577                                        DEBUG(0, ("GSSAPI gss_inquire_cred indicates expiry of %*.*s in %u sec for %s\n",
     578                                                  (int)buffer.length, (int)buffer.length, (char *)buffer.value,
     579                                                  lifetime, usage_string));
     580                                } else {
     581                                        DEBUG(0, ("GSSAPI gss_inquire_cred indicates %*.*s has already expired for %s\n",
     582                                                  (int)buffer.length, (int)buffer.length, (char *)buffer.value,
     583                                                  usage_string));
     584                                }
     585                                gss_release_buffer(&min_stat, &buffer);
     586                                gss_release_name(&min_stat, &name);
     587                        } else if (maj_stat != GSS_S_COMPLETE) {
     588                                DEBUG(0, ("inquiry of credential lifefime via GSSAPI gss_inquire_cred failed: %s\n",
     589                                          gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
     590                        }
     591                        return NT_STATUS_INVALID_PARAMETER;
     592                } else if (smb_gss_oid_equal(gensec_gssapi_state->gss_oid,
     593                                             gss_mech_krb5)) {
    559594                        switch (min_stat) {
    560595                        case KRB5KRB_AP_ERR_TKT_NYV:
     
    569604                                return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */
    570605                        case KRB5_KDC_UNREACH:
    571                                 DEBUG(3, ("Cannot reach a KDC we require in order to obtain a ticetk to %s: %s\n",
     606                                DEBUG(3, ("Cannot reach a KDC we require in order to obtain a ticket to %s: %s\n",
    572607                                          gensec_gssapi_state->target_principal,
    573608                                          gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
     
    586621                                          gensec_gssapi_state->gss_exchange_count,
    587622                                          gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
    588                                 return nt_status;
     623                                return NT_STATUS_LOGON_FAILURE;
    589624                        }
    590625                } else {
     
    593628                                  gensec_gssapi_state->gss_exchange_count,
    594629                                  gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
    595                         return nt_status;
     630                        return NT_STATUS_LOGON_FAILURE;
    596631                }
    597632                break;
     
    942977        if (GSS_ERROR(maj_stat)) {
    943978                TALLOC_CTX *mem_ctx = talloc_new(NULL);
    944                 DEBUG(1, ("gensec_gssapi_max_input_size: determinaing signature size with gss_wrap_size_limit failed: %s\n",
     979                DEBUG(1, ("gensec_gssapi_max_input_size: determining signature size with gss_wrap_size_limit failed: %s\n",
    945980                          gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
    946981                talloc_free(mem_ctx);
     
    9661001        struct gensec_gssapi_state *gensec_gssapi_state
    9671002                = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
    968         OM_uint32 maj_stat, min_stat;
    969         gss_buffer_desc input_token, output_token;
    970         int conf_state;
    971         ssize_t sig_length;
    972 
    973         input_token.length = length;
    974         input_token.value = data;
    975        
    976         maj_stat = gss_wrap(&min_stat,
    977                             gensec_gssapi_state->gssapi_context,
    978                             gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL),
    979                             GSS_C_QOP_DEFAULT,
    980                             &input_token,
    981                             &conf_state,
    982                             &output_token);
    983         if (GSS_ERROR(maj_stat)) {
    984                 DEBUG(1, ("gensec_gssapi_seal_packet: GSS Wrap failed: %s\n",
    985                           gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
    986                 return NT_STATUS_ACCESS_DENIED;
    987         }
    988 
    989         if (output_token.length < input_token.length) {
    990                 DEBUG(1, ("gensec_gssapi_seal_packet: GSS Wrap length [%ld] *less* than caller length [%ld]\n",
    991                           (long)output_token.length, (long)length));
    992                 return NT_STATUS_INTERNAL_ERROR;
    993         }
    994         sig_length = output_token.length - input_token.length;
    995 
    996         memcpy(data, ((uint8_t *)output_token.value) + sig_length, length);
    997         *sig = data_blob_talloc(mem_ctx, (uint8_t *)output_token.value, sig_length);
    998 
    999         dump_data_pw("gensec_gssapi_seal_packet: sig\n", sig->data, sig->length);
    1000         dump_data_pw("gensec_gssapi_seal_packet: clear\n", data, length);
    1001         dump_data_pw("gensec_gssapi_seal_packet: sealed\n", ((uint8_t *)output_token.value) + sig_length, output_token.length - sig_length);
    1002 
    1003         gss_release_buffer(&min_stat, &output_token);
    1004 
    1005         if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)
    1006             && !conf_state) {
    1007                 return NT_STATUS_ACCESS_DENIED;
    1008         }
     1003        bool hdr_signing = false;
     1004        size_t sig_size = 0;
     1005        NTSTATUS status;
     1006
     1007        if (gensec_security->want_features & GENSEC_FEATURE_SIGN_PKT_HEADER) {
     1008                hdr_signing = true;
     1009        }
     1010
     1011        sig_size = gensec_gssapi_sig_size(gensec_security, length);
     1012
     1013        status = gssapi_seal_packet(gensec_gssapi_state->gssapi_context,
     1014                                    gensec_gssapi_state->gss_oid,
     1015                                    hdr_signing, sig_size,
     1016                                    data, length,
     1017                                    whole_pdu, pdu_length,
     1018                                    mem_ctx, sig);
     1019        if (!NT_STATUS_IS_OK(status)) {
     1020                DEBUG(0, ("gssapi_seal_packet(hdr_signing=%u,sig_size=%zu,"
     1021                          "data=%zu,pdu=%zu) failed: %s\n",
     1022                          hdr_signing, sig_size, length, pdu_length,
     1023                          nt_errstr(status)));
     1024                return status;
     1025        }
     1026
    10091027        return NT_STATUS_OK;
    10101028}
    10111029
    10121030static NTSTATUS gensec_gssapi_unseal_packet(struct gensec_security *gensec_security,
    1013                                             TALLOC_CTX *mem_ctx,
    10141031                                            uint8_t *data, size_t length,
    10151032                                            const uint8_t *whole_pdu, size_t pdu_length,
     
    10181035        struct gensec_gssapi_state *gensec_gssapi_state
    10191036                = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
    1020         OM_uint32 maj_stat, min_stat;
    1021         gss_buffer_desc input_token, output_token;
    1022         int conf_state;
    1023         gss_qop_t qop_state;
    1024         DATA_BLOB in;
    1025 
    1026         dump_data_pw("gensec_gssapi_unseal_packet: sig\n", sig->data, sig->length);
    1027 
    1028         in = data_blob_talloc(mem_ctx, NULL, sig->length + length);
    1029 
    1030         memcpy(in.data, sig->data, sig->length);
    1031         memcpy(in.data + sig->length, data, length);
    1032 
    1033         input_token.length = in.length;
    1034         input_token.value = in.data;
    1035        
    1036         maj_stat = gss_unwrap(&min_stat,
    1037                               gensec_gssapi_state->gssapi_context,
    1038                               &input_token,
    1039                               &output_token,
    1040                               &conf_state,
    1041                               &qop_state);
    1042         if (GSS_ERROR(maj_stat)) {
    1043                 DEBUG(1, ("gensec_gssapi_unseal_packet: GSS UnWrap failed: %s\n",
    1044                           gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
    1045                 return NT_STATUS_ACCESS_DENIED;
    1046         }
    1047 
    1048         if (output_token.length != length) {
    1049                 return NT_STATUS_INTERNAL_ERROR;
    1050         }
    1051 
    1052         memcpy(data, output_token.value, length);
    1053 
    1054         gss_release_buffer(&min_stat, &output_token);
    1055        
    1056         if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)
    1057             && !conf_state) {
    1058                 return NT_STATUS_ACCESS_DENIED;
    1059         }
     1037        bool hdr_signing = false;
     1038        NTSTATUS status;
     1039
     1040        if (gensec_security->want_features & GENSEC_FEATURE_SIGN_PKT_HEADER) {
     1041                hdr_signing = true;
     1042        }
     1043
     1044        status = gssapi_unseal_packet(gensec_gssapi_state->gssapi_context,
     1045                                      gensec_gssapi_state->gss_oid,
     1046                                      hdr_signing,
     1047                                      data, length,
     1048                                      whole_pdu, pdu_length,
     1049                                      sig);
     1050        if (!NT_STATUS_IS_OK(status)) {
     1051                DEBUG(0, ("gssapi_unseal_packet(hdr_signing=%u,sig_size=%zu,"
     1052                          "data=%zu,pdu=%zu) failed: %s\n",
     1053                          hdr_signing, sig->length, length, pdu_length,
     1054                          nt_errstr(status)));
     1055                return status;
     1056        }
     1057
    10601058        return NT_STATUS_OK;
    10611059}
     
    10691067        struct gensec_gssapi_state *gensec_gssapi_state
    10701068                = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
    1071         OM_uint32 maj_stat, min_stat;
    1072         gss_buffer_desc input_token, output_token;
     1069        bool hdr_signing = false;
     1070        NTSTATUS status;
    10731071
    10741072        if (gensec_security->want_features & GENSEC_FEATURE_SIGN_PKT_HEADER) {
    1075                 input_token.length = pdu_length;
    1076                 input_token.value = discard_const_p(uint8_t *, whole_pdu);
    1077         } else {
    1078                 input_token.length = length;
    1079                 input_token.value = discard_const_p(uint8_t *, data);
    1080         }
    1081 
    1082         maj_stat = gss_get_mic(&min_stat,
    1083                             gensec_gssapi_state->gssapi_context,
    1084                             GSS_C_QOP_DEFAULT,
    1085                             &input_token,
    1086                             &output_token);
    1087         if (GSS_ERROR(maj_stat)) {
    1088                 DEBUG(1, ("GSS GetMic failed: %s\n",
    1089                           gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
    1090                 return NT_STATUS_ACCESS_DENIED;
    1091         }
    1092 
    1093         *sig = data_blob_talloc(mem_ctx, (uint8_t *)output_token.value, output_token.length);
    1094 
    1095         dump_data_pw("gensec_gssapi_seal_packet: sig\n", sig->data, sig->length);
    1096 
    1097         gss_release_buffer(&min_stat, &output_token);
     1073                hdr_signing = true;
     1074        }
     1075
     1076        status = gssapi_sign_packet(gensec_gssapi_state->gssapi_context,
     1077                                    gensec_gssapi_state->gss_oid,
     1078                                    hdr_signing,
     1079                                    data, length,
     1080                                    whole_pdu, pdu_length,
     1081                                    mem_ctx, sig);
     1082        if (!NT_STATUS_IS_OK(status)) {
     1083                DEBUG(0, ("gssapi_sign_packet(hdr_signing=%u,"
     1084                          "data=%zu,pdu=%zu) failed: %s\n",
     1085                          hdr_signing, length, pdu_length,
     1086                          nt_errstr(status)));
     1087                return status;
     1088        }
    10981089
    10991090        return NT_STATUS_OK;
     
    11011092
    11021093static NTSTATUS gensec_gssapi_check_packet(struct gensec_security *gensec_security,
    1103                                            TALLOC_CTX *mem_ctx,
    11041094                                           const uint8_t *data, size_t length,
    11051095                                           const uint8_t *whole_pdu, size_t pdu_length,
     
    11081098        struct gensec_gssapi_state *gensec_gssapi_state
    11091099                = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
    1110         OM_uint32 maj_stat, min_stat;
    1111         gss_buffer_desc input_token;
    1112         gss_buffer_desc input_message;
    1113         gss_qop_t qop_state;
    1114 
    1115         dump_data_pw("gensec_gssapi_seal_packet: sig\n", sig->data, sig->length);
     1100        bool hdr_signing = false;
     1101        NTSTATUS status;
    11161102
    11171103        if (gensec_security->want_features & GENSEC_FEATURE_SIGN_PKT_HEADER) {
    1118                 input_message.length = pdu_length;
    1119                 input_message.value = discard_const(whole_pdu);
    1120         } else {
    1121                 input_message.length = length;
    1122                 input_message.value = discard_const(data);
    1123         }
    1124 
    1125         input_token.length = sig->length;
    1126         input_token.value = sig->data;
    1127 
    1128         maj_stat = gss_verify_mic(&min_stat,
    1129                               gensec_gssapi_state->gssapi_context,
    1130                               &input_message,
    1131                               &input_token,
    1132                               &qop_state);
    1133         if (GSS_ERROR(maj_stat)) {
    1134                 DEBUG(1, ("GSS VerifyMic failed: %s\n",
    1135                           gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
    1136                 return NT_STATUS_ACCESS_DENIED;
     1104                hdr_signing = true;
     1105        }
     1106
     1107        status = gssapi_check_packet(gensec_gssapi_state->gssapi_context,
     1108                                     gensec_gssapi_state->gss_oid,
     1109                                     hdr_signing,
     1110                                     data, length,
     1111                                     whole_pdu, pdu_length,
     1112                                     sig);
     1113        if (!NT_STATUS_IS_OK(status)) {
     1114                DEBUG(0, ("gssapi_check_packet(hdr_signing=%u,sig_size=%zu,"
     1115                          "data=%zu,pdu=%zu) failed: %s\n",
     1116                          hdr_signing, sig->length, length, pdu_length,
     1117                          nt_errstr(status)));
     1118                return status;
    11371119        }
    11381120
     
    11511133                    && gensec_gssapi_state->sasl_state == STAGE_DONE) {
    11521134                        return ((gensec_gssapi_state->sasl_protection & NEG_SIGN)
    1153                                 && (gensec_gssapi_state->got_flags & GSS_C_INTEG_FLAG));
    1154                 }
    1155                 return gensec_gssapi_state->got_flags & GSS_C_INTEG_FLAG;
     1135                                && (gensec_gssapi_state->gss_got_flags & GSS_C_INTEG_FLAG));
     1136                }
     1137                return gensec_gssapi_state->gss_got_flags & GSS_C_INTEG_FLAG;
    11561138        }
    11571139        if (feature & GENSEC_FEATURE_SEAL) {
     
    11601142                    && gensec_gssapi_state->sasl_state == STAGE_DONE) {
    11611143                        return ((gensec_gssapi_state->sasl_protection & NEG_SEAL)
    1162                                  && (gensec_gssapi_state->got_flags & GSS_C_CONF_FLAG));
    1163                 }
    1164                 return gensec_gssapi_state->got_flags & GSS_C_CONF_FLAG;
     1144                                 && (gensec_gssapi_state->gss_got_flags & GSS_C_CONF_FLAG));
     1145                }
     1146                return gensec_gssapi_state->gss_got_flags & GSS_C_CONF_FLAG;
    11651147        }
    11661148        if (feature & GENSEC_FEATURE_SESSION_KEY) {
    11671149                /* Only for GSSAPI/Krb5 */
    1168                 if (gss_oid_equal(gensec_gssapi_state->gss_oid, gss_mech_krb5)) {
     1150                if (smb_gss_oid_equal(gensec_gssapi_state->gss_oid,
     1151                                      gss_mech_krb5)) {
    11691152                        return true;
    11701153                }
    11711154        }
    11721155        if (feature & GENSEC_FEATURE_DCE_STYLE) {
    1173                 return gensec_gssapi_state->got_flags & GSS_C_DCE_STYLE;
     1156                return gensec_gssapi_state->gss_got_flags & GSS_C_DCE_STYLE;
    11741157        }
    11751158        if (feature & GENSEC_FEATURE_NEW_SPNEGO) {
    11761159                NTSTATUS status;
    1177 
    1178                 if (!(gensec_gssapi_state->got_flags & GSS_C_INTEG_FLAG)) {
     1160                uint32_t keytype;
     1161
     1162                if (!(gensec_gssapi_state->gss_got_flags & GSS_C_INTEG_FLAG)) {
    11791163                        return false;
    11801164                }
     
    11871171                }
    11881172
    1189                 status = gensec_gssapi_init_lucid(gensec_gssapi_state);
    1190                 if (!NT_STATUS_IS_OK(status)) {
    1191                         return false;
    1192                 }
    1193 
    1194                 if (gensec_gssapi_state->lucid->protocol == 1) {
    1195                         return true;
    1196                 }
    1197 
    1198                 return false;
     1173                status = gssapi_get_session_key(gensec_gssapi_state,
     1174                                                gensec_gssapi_state->gssapi_context, NULL, &keytype);
     1175                /*
     1176                 * We should do a proper sig on the mechListMic unless
     1177                 * we know we have to be backwards compatible with
     1178                 * earlier windows versions. 
     1179                 *
     1180                 * Negotiating a non-krb5
     1181                 * mech for example should be regarded as having
     1182                 * NEW_SPNEGO
     1183                 */
     1184                if (NT_STATUS_IS_OK(status)) {
     1185                        switch (keytype) {
     1186                        case ENCTYPE_DES_CBC_CRC:
     1187                        case ENCTYPE_DES_CBC_MD5:
     1188                        case ENCTYPE_ARCFOUR_HMAC:
     1189                        case ENCTYPE_DES3_CBC_SHA1:
     1190                                return false;
     1191                        }
     1192                }
     1193                return true;
    11991194        }
    12001195        /* We can always do async (rather than strict request/reply) packets.  */
     
    12021197                return true;
    12031198        }
     1199        if (feature & GENSEC_FEATURE_SIGN_PKT_HEADER) {
     1200                if (gensec_security->want_features & GENSEC_FEATURE_SEAL) {
     1201                        return true;
     1202                }
     1203
     1204                if (gensec_security->want_features & GENSEC_FEATURE_SIGN) {
     1205                        return true;
     1206                }
     1207
     1208                return false;
     1209        }
    12041210        return false;
     1211}
     1212
     1213static NTTIME gensec_gssapi_expire_time(struct gensec_security *gensec_security)
     1214{
     1215        struct gensec_gssapi_state *gensec_gssapi_state =
     1216                talloc_get_type_abort(gensec_security->private_data,
     1217                struct gensec_gssapi_state);
     1218
     1219        return gensec_gssapi_state->expire_time;
    12051220}
    12061221
     
    12121227 */
    12131228static NTSTATUS gensec_gssapi_session_key(struct gensec_security *gensec_security,
     1229                                          TALLOC_CTX *mem_ctx,
    12141230                                          DATA_BLOB *session_key)
    12151231{
    12161232        struct gensec_gssapi_state *gensec_gssapi_state
    12171233                = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
    1218         OM_uint32 maj_stat, min_stat;
    1219         krb5_keyblock *subkey;
    1220 
    1221         if (gensec_gssapi_state->sasl_state != STAGE_DONE) {
    1222                 return NT_STATUS_NO_USER_SESSION_KEY;
    1223         }
    1224 
    1225         if (gensec_gssapi_state->session_key.data) {
    1226                 *session_key = gensec_gssapi_state->session_key;
    1227                 return NT_STATUS_OK;
    1228         }
    1229 
    1230         maj_stat = gsskrb5_get_subkey(&min_stat,
    1231                                       gensec_gssapi_state->gssapi_context,
    1232                                       &subkey);
    1233         if (maj_stat != 0) {
    1234                 DEBUG(1, ("NO session key for this mech\n"));
    1235                 return NT_STATUS_NO_USER_SESSION_KEY;
    1236         }
    1237        
    1238         DEBUG(10, ("Got KRB5 session key of length %d%s\n",
    1239                    (int)KRB5_KEY_LENGTH(subkey),
    1240                    (gensec_gssapi_state->sasl_state == STAGE_DONE)?" (done)":""));
    1241         *session_key = data_blob_talloc(gensec_gssapi_state,
    1242                                         KRB5_KEY_DATA(subkey), KRB5_KEY_LENGTH(subkey));
    1243         krb5_free_keyblock(gensec_gssapi_state->smb_krb5_context->krb5_context, subkey);
    1244         gensec_gssapi_state->session_key = *session_key;
    1245         dump_data_pw("KRB5 Session Key:\n", session_key->data, session_key->length);
    1246 
    1247         return NT_STATUS_OK;
     1234        return gssapi_get_session_key(mem_ctx, gensec_gssapi_state->gssapi_context, session_key, NULL);
    12481235}
    12491236
     
    12521239 * database lookup */
    12531240static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_security,
     1241                                           TALLOC_CTX *mem_ctx,
    12541242                                           struct auth_session_info **_session_info)
    12551243{
    12561244        NTSTATUS nt_status;
    1257         TALLOC_CTX *mem_ctx;
     1245        TALLOC_CTX *tmp_ctx;
    12581246        struct gensec_gssapi_state *gensec_gssapi_state
    12591247                = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
    1260         struct auth_user_info_dc *user_info_dc = NULL;
    12611248        struct auth_session_info *session_info = NULL;
    12621249        OM_uint32 maj_stat, min_stat;
    1263         gss_buffer_desc pac;
    1264         DATA_BLOB pac_blob;
    1265         struct PAC_SIGNATURE_DATA *pac_srv_sig = NULL;
    1266         struct PAC_SIGNATURE_DATA *pac_kdc_sig = NULL;
     1250        DATA_BLOB pac_blob, *pac_blob_ptr = NULL;
     1251
     1252        gss_buffer_desc name_token;
     1253        char *principal_string;
    12671254       
    1268         if ((gensec_gssapi_state->gss_oid->length != gss_mech_krb5->length)
    1269             || (memcmp(gensec_gssapi_state->gss_oid->elements, gss_mech_krb5->elements,
    1270                        gensec_gssapi_state->gss_oid->length) != 0)) {
    1271                 DEBUG(1, ("NO session info available for this mech\n"));
    1272                 return NT_STATUS_INVALID_PARAMETER;
    1273         }
    1274                
    1275         mem_ctx = talloc_named(gensec_gssapi_state, 0, "gensec_gssapi_session_info context");
    1276         NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
    1277 
    1278         maj_stat = gsskrb5_extract_authz_data_from_sec_context(&min_stat,
    1279                                                                gensec_gssapi_state->gssapi_context,
    1280                                                                KRB5_AUTHDATA_WIN2K_PAC,
    1281                                                                &pac);
    1282        
    1283        
    1284         if (maj_stat == 0) {
    1285                 pac_blob = data_blob_talloc(mem_ctx, pac.value, pac.length);
    1286                 gss_release_buffer(&min_stat, &pac);
    1287 
    1288         } else {
    1289                 pac_blob = data_blob(NULL, 0);
    1290         }
     1255        tmp_ctx = talloc_named(mem_ctx, 0, "gensec_gssapi_session_info context");
     1256        NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
     1257
     1258        maj_stat = gss_display_name (&min_stat,
     1259                                     gensec_gssapi_state->client_name,
     1260                                     &name_token,
     1261                                     NULL);
     1262        if (GSS_ERROR(maj_stat)) {
     1263                DEBUG(1, ("GSS display_name failed: %s\n",
     1264                          gssapi_error_string(tmp_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
     1265                talloc_free(tmp_ctx);
     1266                return NT_STATUS_FOOBAR;
     1267        }
     1268
     1269        principal_string = talloc_strndup(tmp_ctx,
     1270                                          (const char *)name_token.value,
     1271                                          name_token.length);
     1272
     1273        gss_release_buffer(&min_stat, &name_token);
     1274
     1275        if (!principal_string) {
     1276                talloc_free(tmp_ctx);
     1277                return NT_STATUS_NO_MEMORY;
     1278        }
     1279
     1280        nt_status = gssapi_obtain_pac_blob(tmp_ctx,  gensec_gssapi_state->gssapi_context,
     1281                                           gensec_gssapi_state->client_name,
     1282                                           &pac_blob);
    12911283       
    12921284        /* IF we have the PAC - otherwise we need to get this
     
    12941286         * kind...
    12951287         */
    1296         if (pac_blob.length) {
    1297                 pac_srv_sig = talloc(mem_ctx, struct PAC_SIGNATURE_DATA);
    1298                 if (!pac_srv_sig) {
    1299                         talloc_free(mem_ctx);
    1300                         return NT_STATUS_NO_MEMORY;
    1301                 }
    1302                 pac_kdc_sig = talloc(mem_ctx, struct PAC_SIGNATURE_DATA);
    1303                 if (!pac_kdc_sig) {
    1304                         talloc_free(mem_ctx);
    1305                         return NT_STATUS_NO_MEMORY;
    1306                 }
    1307 
    1308                 nt_status = kerberos_pac_blob_to_user_info_dc(mem_ctx,
    1309                                                               pac_blob,
    1310                                                               gensec_gssapi_state->smb_krb5_context->krb5_context,
    1311                                                               &user_info_dc,
    1312                                                               pac_srv_sig,
    1313                                                               pac_kdc_sig);
    1314                 if (!NT_STATUS_IS_OK(nt_status)) {
    1315                         talloc_free(mem_ctx);
    1316                         return nt_status;
    1317                 }
    1318         } else {
    1319                 gss_buffer_desc name_token;
    1320                 char *principal_string;
    1321 
    1322                 maj_stat = gss_display_name (&min_stat,
    1323                                              gensec_gssapi_state->client_name,
    1324                                              &name_token,
    1325                                              NULL);
    1326                 if (GSS_ERROR(maj_stat)) {
    1327                         DEBUG(1, ("GSS display_name failed: %s\n",
    1328                                   gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
    1329                         talloc_free(mem_ctx);
    1330                         return NT_STATUS_FOOBAR;
    1331                 }
    1332                
    1333                 principal_string = talloc_strndup(mem_ctx,
    1334                                                   (const char *)name_token.value,
    1335                                                   name_token.length);
    1336                
    1337                 gss_release_buffer(&min_stat, &name_token);
    1338                
    1339                 if (!principal_string) {
    1340                         talloc_free(mem_ctx);
    1341                         return NT_STATUS_NO_MEMORY;
    1342                 }
    1343 
    1344                 if (gensec_security->auth_context &&
    1345                     !gensec_setting_bool(gensec_security->settings, "gensec", "require_pac", false)) {
    1346                         DEBUG(1, ("Unable to find PAC, resorting to local user lookup: %s\n",
    1347                                   gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
    1348                         nt_status = gensec_security->auth_context->get_user_info_dc_principal(mem_ctx,
    1349                                                                                              gensec_security->auth_context,
    1350                                                                                              principal_string,
    1351                                                                                              NULL,
    1352                                                                                              &user_info_dc);
    1353                        
    1354                         if (!NT_STATUS_IS_OK(nt_status)) {
    1355                                 talloc_free(mem_ctx);
    1356                                 return nt_status;
    1357                         }
    1358                 } else {
    1359                         DEBUG(1, ("Unable to find PAC in ticket from %s, failing to allow access: %s\n",
    1360                                   principal_string,
    1361                                   gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
    1362                         return NT_STATUS_ACCESS_DENIED;
    1363                 }
    1364         }
    1365 
    1366         /* references the user_info_dc into the session_info */
    1367         nt_status = gensec_generate_session_info(mem_ctx, gensec_security,
    1368                                                  user_info_dc, &session_info);
     1288        if (NT_STATUS_IS_OK(nt_status)) {
     1289                pac_blob_ptr = &pac_blob;
     1290        }
     1291        nt_status = gensec_generate_session_info_pac(tmp_ctx,
     1292                                                     gensec_security,
     1293                                                     gensec_gssapi_state->smb_krb5_context,
     1294                                                     pac_blob_ptr, principal_string,
     1295                                                     gensec_get_remote_address(gensec_security),
     1296                                                     &session_info);
    13691297        if (!NT_STATUS_IS_OK(nt_status)) {
    1370                 talloc_free(mem_ctx);
     1298                talloc_free(tmp_ctx);
    13711299                return nt_status;
    13721300        }
    13731301
    1374         nt_status = gensec_gssapi_session_key(gensec_security, &session_info->session_key);
     1302        nt_status = gensec_gssapi_session_key(gensec_security, session_info, &session_info->session_key);
    13751303        if (!NT_STATUS_IS_OK(nt_status)) {
    1376                 talloc_free(mem_ctx);
     1304                talloc_free(tmp_ctx);
    13771305                return nt_status;
    13781306        }
    13791307
    1380         /* Allow torture tests to check the PAC signatures */
    1381         if (session_info->torture) {
    1382                 session_info->torture->pac_srv_sig = talloc_steal(session_info->torture, pac_srv_sig);
    1383                 session_info->torture->pac_kdc_sig = talloc_steal(session_info->torture, pac_kdc_sig);
    1384         }
    1385 
    1386         if (!(gensec_gssapi_state->got_flags & GSS_C_DELEG_FLAG)) {
    1387                 DEBUG(10, ("gensec_gssapi: NO delegated credentials supplied by client\n"));
    1388         } else {
     1308        if (gensec_gssapi_state->gss_got_flags & GSS_C_DELEG_FLAG &&
     1309            gensec_gssapi_state->delegated_cred_handle != GSS_C_NO_CREDENTIAL) {
    13891310                krb5_error_code ret;
    13901311                const char *error_string;
     
    13931314                session_info->credentials = cli_credentials_init(session_info);
    13941315                if (!session_info->credentials) {
    1395                         talloc_free(mem_ctx);
     1316                        talloc_free(tmp_ctx);
    13961317                        return NT_STATUS_NO_MEMORY;
    13971318                }
     
    14061327                                                           CRED_SPECIFIED, &error_string);
    14071328                if (ret) {
    1408                         talloc_free(mem_ctx);
     1329                        talloc_free(tmp_ctx);
    14091330                        DEBUG(2,("Failed to get gss creds: %s\n", error_string));
    14101331                        return NT_STATUS_NO_MEMORY;
     
    14161337                /* It has been taken from this place... */
    14171338                gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL;
    1418         }
    1419         talloc_steal(gensec_gssapi_state, session_info);
    1420         talloc_free(mem_ctx);
    1421         *_session_info = session_info;
     1339        } else {
     1340                DEBUG(10, ("gensec_gssapi: NO delegated credentials supplied by client\n"));
     1341        }
     1342
     1343        *_session_info = talloc_steal(mem_ctx, session_info);
     1344        talloc_free(tmp_ctx);
    14221345
    14231346        return NT_STATUS_OK;
     
    14281351        struct gensec_gssapi_state *gensec_gssapi_state
    14291352                = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
    1430         NTSTATUS status;
    1431 
    1432         if (gensec_gssapi_state->sig_size) {
     1353        size_t sig_size;
     1354
     1355        if (gensec_gssapi_state->sig_size > 0) {
    14331356                return gensec_gssapi_state->sig_size;
    14341357        }
    14351358
    1436         if (gensec_gssapi_state->got_flags & GSS_C_CONF_FLAG) {
    1437                 gensec_gssapi_state->sig_size = 45;
    1438         } else {
    1439                 gensec_gssapi_state->sig_size = 37;
    1440         }
    1441 
    1442         status = gensec_gssapi_init_lucid(gensec_gssapi_state);
    1443         if (!NT_STATUS_IS_OK(status)) {
    1444                 return gensec_gssapi_state->sig_size;
    1445         }
    1446 
    1447         if (gensec_gssapi_state->lucid->protocol == 1) {
    1448                 if (gensec_gssapi_state->got_flags & GSS_C_CONF_FLAG) {
    1449                         /*
    1450                          * TODO: windows uses 76 here, but we don't know
    1451                          *       gss_wrap works with aes keys yet
    1452                          */
    1453                         gensec_gssapi_state->sig_size = 76;
    1454                 } else {
    1455                         gensec_gssapi_state->sig_size = 28;
    1456                 }
    1457         } else if (gensec_gssapi_state->lucid->protocol == 0) {
    1458                 switch (gensec_gssapi_state->lucid->rfc1964_kd.ctx_key.type) {
    1459                 case KEYTYPE_DES:
    1460                 case KEYTYPE_ARCFOUR:
    1461                 case KEYTYPE_ARCFOUR_56:
    1462                         if (gensec_gssapi_state->got_flags & GSS_C_CONF_FLAG) {
    1463                                 gensec_gssapi_state->sig_size = 45;
    1464                         } else {
    1465                                 gensec_gssapi_state->sig_size = 37;
    1466                         }
    1467                         break;
    1468                 case KEYTYPE_DES3:
    1469                         if (gensec_gssapi_state->got_flags & GSS_C_CONF_FLAG) {
    1470                                 gensec_gssapi_state->sig_size = 57;
    1471                         } else {
    1472                                 gensec_gssapi_state->sig_size = 49;
    1473                         }
    1474                         break;
    1475                 }
    1476         }
    1477 
     1359        sig_size = gssapi_get_sig_size(gensec_gssapi_state->gssapi_context,
     1360                                       gensec_gssapi_state->gss_oid,
     1361                                       gensec_gssapi_state->gss_want_flags,
     1362                                       data_size);
     1363
     1364        gensec_gssapi_state->sig_size = sig_size;
    14781365        return gensec_gssapi_state->sig_size;
    14791366}
     
    14981385        .client_start   = gensec_gssapi_client_start,
    14991386        .server_start   = gensec_gssapi_server_start,
    1500         .magic          = gensec_gssapi_magic,
     1387        .magic          = gensec_magic_check_krb5_oid,
    15011388        .update         = gensec_gssapi_update,
    15021389        .session_key    = gensec_gssapi_session_key,
     
    15061393        .seal_packet    = gensec_gssapi_seal_packet,
    15071394        .unseal_packet  = gensec_gssapi_unseal_packet,
     1395        .max_input_size   = gensec_gssapi_max_input_size,
     1396        .max_wrapped_size = gensec_gssapi_max_wrapped_size,
    15081397        .wrap           = gensec_gssapi_wrap,
    15091398        .unwrap         = gensec_gssapi_unwrap,
    15101399        .have_feature   = gensec_gssapi_have_feature,
     1400        .expire_time    = gensec_gssapi_expire_time,
    15111401        .enabled        = false,
    15121402        .kerberos       = true,
     
    15211411        .client_start   = gensec_gssapi_client_start,
    15221412        .server_start   = gensec_gssapi_server_start,
    1523         .magic          = gensec_gssapi_magic,
     1413        .magic          = gensec_magic_check_krb5_oid,
    15241414        .update         = gensec_gssapi_update,
    15251415        .session_key    = gensec_gssapi_session_key,
     
    15301420        .seal_packet    = gensec_gssapi_seal_packet,
    15311421        .unseal_packet  = gensec_gssapi_unseal_packet,
     1422        .max_input_size   = gensec_gssapi_max_input_size,
     1423        .max_wrapped_size = gensec_gssapi_max_wrapped_size,
    15321424        .wrap           = gensec_gssapi_wrap,
    15331425        .unwrap         = gensec_gssapi_unwrap,
    15341426        .have_feature   = gensec_gssapi_have_feature,
     1427        .expire_time    = gensec_gssapi_expire_time,
    15351428        .enabled        = true,
    15361429        .kerberos       = true,
     
    15521445        .unwrap           = gensec_gssapi_unwrap,
    15531446        .have_feature     = gensec_gssapi_have_feature,
     1447        .expire_time      = gensec_gssapi_expire_time,
    15541448        .enabled          = true,
    15551449        .kerberos         = true,
  • vendor/current/source4/auth/gensec/gensec_gssapi.h

    r740 r988  
    1 /* 
     1/*
    22   Unix SMB/CIFS implementation.
    33
    44   Kerberos backend for GENSEC
    5    
     5
    66   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005
    77   Copyright (C) Stefan Metzmacher <metze@samba.org> 2004-2005
     
    1111   the Free Software Foundation; either version 3 of the License, or
    1212   (at your option) any later version.
    13    
     13
    1414   This program is distributed in the hope that it will be useful,
    1515   but WITHOUT ANY WARRANTY; without even the implied warranty of
     
    1717   GNU General Public License for more details.
    1818
    19    
     19
    2020   You should have received a copy of the GNU General Public License
    2121   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    2424/* This structure described here, so the RPC-PAC test can get at the PAC provided */
    2525
    26 enum gensec_gssapi_sasl_state 
     26enum gensec_gssapi_sasl_state
    2727{
    2828        STAGE_GSS_NEG,
     
    3838struct gensec_gssapi_state {
    3939        gss_ctx_id_t gssapi_context;
    40         struct gss_channel_bindings_struct *input_chan_bindings;
    4140        gss_name_t server_name;
    4241        gss_name_t client_name;
    43         OM_uint32 want_flags, got_flags;
     42        OM_uint32 gss_want_flags, gss_got_flags;
     43
     44        gss_cred_id_t delegated_cred_handle;
     45
     46        NTTIME expire_time;
     47
     48        /* gensec_gssapi only */
    4449        gss_OID gss_oid;
    4550
    46         DATA_BLOB session_key;
    47         DATA_BLOB pac;
    48 
     51        struct gss_channel_bindings_struct *input_chan_bindings;
    4952        struct smb_krb5_context *smb_krb5_context;
    5053        struct gssapi_creds_container *client_cred;
    5154        struct gssapi_creds_container *server_cred;
    52         gss_krb5_lucid_context_v1_t *lucid;
    53 
    54         gss_cred_id_t delegated_cred_handle;
    5555
    5656        bool sasl; /* We have two different mechs in this file: One
     
    6868        const char *target_principal;
    6969};
    70 
  • vendor/current/source4/auth/gensec/gensec_krb5.c

    r740 r988  
    2828#include "auth/kerberos/kerberos.h"
    2929#include "auth/auth.h"
    30 #include "lib/socket/socket.h"
    3130#include "lib/tsocket/tsocket.h"
    32 #include "librpc/rpc/dcerpc.h"
     31#include "librpc/gen_ndr/dcerpc.h"
    3332#include "auth/credentials/credentials.h"
    3433#include "auth/credentials/credentials_krb5.h"
    3534#include "auth/kerberos/kerberos_credentials.h"
    3635#include "auth/gensec/gensec.h"
     36#include "auth/gensec/gensec_internal.h"
    3737#include "auth/gensec/gensec_proto.h"
     38#include "auth/gensec/gensec_toplevel_proto.h"
    3839#include "param/param.h"
    3940#include "auth/auth_sam_reply.h"
    4041#include "lib/util/util_net.h"
     42#include "../lib/util/asn1.h"
     43#include "auth/kerberos/pac_utils.h"
     44#include "gensec_krb5_util.h"
     45
     46_PUBLIC_ NTSTATUS gensec_krb5_init(void);
    4147
    4248enum GENSEC_KRB5_STATE {
     
    4854
    4955struct gensec_krb5_state {
    50         DATA_BLOB session_key;
    51         DATA_BLOB pac;
    5256        enum GENSEC_KRB5_STATE state_position;
    5357        struct smb_krb5_context *smb_krb5_context;
     
    113117        ZERO_STRUCT(gensec_krb5_state->enc_ticket);
    114118        gensec_krb5_state->keyblock = NULL;
    115         gensec_krb5_state->session_key = data_blob(NULL, 0);
    116         gensec_krb5_state->pac = data_blob(NULL, 0);
    117119        gensec_krb5_state->gssapi = gssapi;
    118120
     
    234236static NTSTATUS gensec_krb5_common_client_start(struct gensec_security *gensec_security, bool gssapi)
    235237{
     238        const char *hostname;
    236239        struct gensec_krb5_state *gensec_krb5_state;
    237         krb5_error_code ret;
    238240        NTSTATUS nt_status;
    239         struct ccache_container *ccache_container;
    240         const char *hostname;
    241         const char *error_string;
    242         const char *principal;
    243         krb5_data in_data;
    244         struct tevent_context *previous_ev;
    245 
    246241        hostname = gensec_get_target_hostname(gensec_security);
    247242        if (!hostname) {
    248                 DEBUG(1, ("Could not determine hostname for target computer, cannot use kerberos\n"));
     243                DEBUG(3, ("No hostname for target computer passed in, cannot use kerberos for this connection\n"));
    249244                return NT_STATUS_INVALID_PARAMETER;
    250245        }
     
    268263
    269264        if (gensec_krb5_state->gssapi) {
    270                 /* The Fake GSSAPI modal emulates Samba3, which does not do mutual authentication */
     265                /* The Fake GSSAPI model emulates Samba3, which does not do mutual authentication */
    271266                if (gensec_setting_bool(gensec_security->settings, "gensec_fake_gssapi_krb5", "mutual", false)) {
    272267                        gensec_krb5_state->ap_req_options |= AP_OPTS_MUTUAL_REQUIRED;
     
    278273                }
    279274        }
     275        return NT_STATUS_OK;
     276}
     277
     278static NTSTATUS gensec_krb5_common_client_creds(struct gensec_security *gensec_security,
     279                                                struct tevent_context *ev,
     280                                                bool gssapi)
     281{
     282        struct gensec_krb5_state *gensec_krb5_state;
     283        krb5_error_code ret;
     284        struct ccache_container *ccache_container;
     285        const char *error_string;
     286        const char *principal;
     287        const char *hostname;
     288        krb5_data in_data = { .length = 0 };
     289        krb5_data *in_data_p = NULL;
     290        struct tevent_context *previous_ev;
     291
     292        if (lpcfg_parm_bool(gensec_security->settings->lp_ctx,
     293                            NULL, "gensec_krb5", "send_authenticator_checksum", true)) {
     294                in_data_p = &in_data;
     295        }
     296       
     297        gensec_krb5_state = (struct gensec_krb5_state *)gensec_security->private_data;
    280298
    281299        principal = gensec_get_target_principal(gensec_security);
     300        hostname = gensec_get_target_hostname(gensec_security);
    282301
    283302        ret = cli_credentials_get_ccache(gensec_get_credentials(gensec_security),
    284                                          gensec_security->event_ctx,
     303                                         ev,
    285304                                         gensec_security->settings->lp_ctx, &ccache_container, &error_string);
    286305        switch (ret) {
     
    301320                return NT_STATUS_UNSUCCESSFUL;
    302321        }
    303         in_data.length = 0;
    304322       
    305323        /* Do this every time, in case we have weird recursive issues here */
    306         ret = smb_krb5_context_set_event_ctx(gensec_krb5_state->smb_krb5_context, gensec_security->event_ctx, &previous_ev);
     324        ret = smb_krb5_context_set_event_ctx(gensec_krb5_state->smb_krb5_context, ev, &previous_ev);
    307325        if (ret != 0) {
    308326                DEBUG(1, ("gensec_krb5_start: Setting event context failed\n"));
     
    318336                                                gensec_krb5_state->ap_req_options,
    319337                                                target_principal,
    320                                                 &in_data, ccache_container->ccache,
     338                                                in_data_p, ccache_container->ccache,
    321339                                                &gensec_krb5_state->enc_ticket);
    322340                        krb5_free_principal(gensec_krb5_state->smb_krb5_context->krb5_context,
     
    329347                                  gensec_get_target_service(gensec_security),
    330348                                  hostname,
    331                                   &in_data, ccache_container->ccache,
     349                                  in_data_p, ccache_container->ccache,
    332350                                  &gensec_krb5_state->enc_ticket);
    333351        }
    334352
    335         smb_krb5_context_remove_event_ctx(gensec_krb5_state->smb_krb5_context, previous_ev, gensec_security->event_ctx);
     353        smb_krb5_context_remove_event_ctx(gensec_krb5_state->smb_krb5_context, previous_ev, ev);
    336354
    337355        switch (ret) {
     
    383401}
    384402
    385 /**
    386  * Check if the packet is one for this mechansim
    387  *
    388  * @param gensec_security GENSEC state
    389  * @param in The request, as a DATA_BLOB
    390  * @return Error, INVALID_PARAMETER if it's not a packet for us
    391  *                or NT_STATUS_OK if the packet is ok.
    392  */
    393 
    394 static NTSTATUS gensec_fake_gssapi_krb5_magic(struct gensec_security *gensec_security,
    395                                   const DATA_BLOB *in)
    396 {
    397         if (gensec_gssapi_check_oid(in, GENSEC_OID_KERBEROS5)) {
    398                 return NT_STATUS_OK;
     403
     404/*
     405  generate a krb5 GSS-API wrapper packet given a ticket
     406*/
     407static DATA_BLOB gensec_gssapi_gen_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLOB *ticket, const uint8_t tok_id[2])
     408{
     409        struct asn1_data *data;
     410        DATA_BLOB ret = data_blob_null;
     411
     412        data = asn1_init(mem_ctx);
     413        if (!data || !ticket->data) {
     414                return ret;
     415        }
     416
     417        if (!asn1_push_tag(data, ASN1_APPLICATION(0))) goto err;
     418        if (!asn1_write_OID(data, GENSEC_OID_KERBEROS5)) goto err;
     419
     420        if (!asn1_write(data, tok_id, 2)) goto err;
     421        if (!asn1_write(data, ticket->data, ticket->length)) goto err;
     422        if (!asn1_pop_tag(data)) goto err;
     423
     424
     425        if (!asn1_extract_blob(data, mem_ctx, &ret)) {
     426                goto err;
     427        }
     428        asn1_free(data);
     429
     430        return ret;
     431
     432  err:
     433
     434        DEBUG(1, ("Failed to build krb5 wrapper at offset %d\n",
     435                  (int)asn1_current_ofs(data)));
     436        asn1_free(data);
     437        return ret;
     438}
     439
     440/*
     441  parse a krb5 GSS-API wrapper packet giving a ticket
     442*/
     443static bool gensec_gssapi_parse_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, DATA_BLOB *ticket, uint8_t tok_id[2])
     444{
     445        bool ret = false;
     446        struct asn1_data *data = asn1_init(mem_ctx);
     447        int data_remaining;
     448
     449        if (!data) {
     450                return false;
     451        }
     452
     453        if (!asn1_load(data, *blob)) goto err;
     454        if (!asn1_start_tag(data, ASN1_APPLICATION(0))) goto err;
     455        if (!asn1_check_OID(data, GENSEC_OID_KERBEROS5)) goto err;
     456
     457        data_remaining = asn1_tag_remaining(data);
     458
     459        if (data_remaining < 3) {
     460                asn1_set_error(data);
    399461        } else {
    400                 return NT_STATUS_INVALID_PARAMETER;
    401         }
    402 }
    403 
     462                if (!asn1_read(data, tok_id, 2)) goto err;
     463                data_remaining -= 2;
     464                *ticket = data_blob_talloc(mem_ctx, NULL, data_remaining);
     465                if (!asn1_read(data, ticket->data, ticket->length)) goto err;
     466        }
     467
     468        if (!asn1_end_tag(data)) goto err;
     469
     470        ret = !asn1_has_error(data);
     471
     472  err:
     473
     474        asn1_free(data);
     475
     476        return ret;
     477}
    404478
    405479/**
     
    416490static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security,
    417491                                   TALLOC_CTX *out_mem_ctx,
     492                                   struct tevent_context *ev,
    418493                                   const DATA_BLOB in, DATA_BLOB *out)
    419494{
     
    427502                DATA_BLOB unwrapped_out;
    428503               
     504                nt_status = gensec_krb5_common_client_creds(gensec_security, ev, gensec_krb5_state->gssapi);
     505                if (!NT_STATUS_IS_OK(nt_status)) {
     506                        return nt_status;
     507                }
     508
    429509                if (gensec_krb5_state->gssapi) {
    430510                        unwrapped_out = data_blob_talloc(out_mem_ctx, gensec_krb5_state->enc_ticket.data, gensec_krb5_state->enc_ticket.length);
     
    506586                }
    507587               
    508                 /* This ensures we lookup the correct entry in that keytab */
     588                /* This ensures we lookup the correct entry in that
     589                 * keytab.  A NULL principal is acceptable, and means
     590                 * that the krb5 libs should search the keytab at
     591                 * accept time for any matching key */
    509592                ret = principal_from_credentials(out_mem_ctx, gensec_get_credentials(gensec_security),
    510593                                                 gensec_krb5_state->smb_krb5_context,
     
    514597                        DEBUG(2,("Failed to make credentials from principal: %s\n", error_string));
    515598                        return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
     599                }
     600
     601                if (keytab->password_based || obtained < CRED_SPECIFIED) {
     602                        /*
     603                         * Use match-by-key in this case (matches
     604                         * cli_credentials_get_server_gss_creds()
     605                         * behaviour).  No need to free the memory,
     606                         * this is handled with a talloc destructor.
     607                         */
     608                        server_in_keytab = NULL;
    516609                }
    517610
     
    557650
    558651static NTSTATUS gensec_krb5_session_key(struct gensec_security *gensec_security,
     652                                        TALLOC_CTX *mem_ctx,
    559653                                        DATA_BLOB *session_key)
    560654{
     
    567661        if (gensec_krb5_state->state_position != GENSEC_KRB5_DONE) {
    568662                return NT_STATUS_NO_USER_SESSION_KEY;
    569         }
    570 
    571         if (gensec_krb5_state->session_key.data) {
    572                 *session_key = gensec_krb5_state->session_key;
    573                 return NT_STATUS_OK;
    574663        }
    575664
     
    585674                DEBUG(10, ("Got KRB5 session key of length %d\n", 
    586675                           (int)KRB5_KEY_LENGTH(skey)));
    587                 gensec_krb5_state->session_key = data_blob_talloc(gensec_krb5_state,
    588                                                 KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey));
    589                 *session_key = gensec_krb5_state->session_key;
     676                *session_key = data_blob_talloc(mem_ctx,
     677                                               KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey));
    590678                dump_data_pw("KRB5 Session Key:\n", session_key->data, session_key->length);
    591679
     
    599687
    600688static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security,
     689                                         TALLOC_CTX *mem_ctx,
    601690                                         struct auth_session_info **_session_info)
    602691{
     
    604693        struct gensec_krb5_state *gensec_krb5_state = (struct gensec_krb5_state *)gensec_security->private_data;
    605694        krb5_context context = gensec_krb5_state->smb_krb5_context->krb5_context;
    606         struct auth_user_info_dc *user_info_dc = NULL;
    607695        struct auth_session_info *session_info = NULL;
    608         struct PAC_LOGON_INFO *logon_info;
    609696
    610697        krb5_principal client_principal;
    611698        char *principal_string;
    612699       
    613         DATA_BLOB pac;
     700        DATA_BLOB pac_blob, *pac_blob_ptr = NULL;
    614701        krb5_data pac_data;
    615702
    616703        krb5_error_code ret;
    617704
    618         TALLOC_CTX *mem_ctx = talloc_new(gensec_security);
    619         if (!mem_ctx) {
     705        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     706        if (!tmp_ctx) {
    620707                return NT_STATUS_NO_MEMORY;
    621708        }
     
    625712                DEBUG(5, ("krb5_ticket_get_client failed to get cleint principal: %s\n",
    626713                          smb_get_krb5_error_message(context,
    627                                                      ret, mem_ctx)));
    628                 talloc_free(mem_ctx);
     714                                                     ret, tmp_ctx)));
     715                talloc_free(tmp_ctx);
    629716                return NT_STATUS_NO_MEMORY;
    630717        }
     
    635722                DEBUG(1, ("Unable to parse client principal: %s\n",
    636723                          smb_get_krb5_error_message(context,
    637                                                      ret, mem_ctx)));
     724                                                     ret, tmp_ctx)));
    638725                krb5_free_principal(context, client_principal);
    639                 talloc_free(mem_ctx);
     726                talloc_free(tmp_ctx);
    640727                return NT_STATUS_NO_MEMORY;
    641728        }
     
    645732                                                      &pac_data);
    646733       
    647         if (ret && gensec_setting_bool(gensec_security->settings, "gensec", "require_pac", false)) {
    648                 DEBUG(1, ("Unable to find PAC in ticket from %s, failing to allow access: %s \n",
    649                           principal_string,
    650                           smb_get_krb5_error_message(context,
    651                                                      ret, mem_ctx)));
    652                 free(principal_string);
    653                 krb5_free_principal(context, client_principal);
    654                 talloc_free(mem_ctx);
    655                 return NT_STATUS_ACCESS_DENIED;
    656         } else if (ret) {
     734        if (ret) {
    657735                /* NO pac */
    658736                DEBUG(5, ("krb5_ticket_get_authorization_data_type failed to find PAC: %s\n",
    659737                          smb_get_krb5_error_message(context,
    660                                                      ret, mem_ctx)));
    661                 if (gensec_security->auth_context &&
    662                     !gensec_setting_bool(gensec_security->settings, "gensec", "require_pac", false)) {
    663                         DEBUG(1, ("Unable to find PAC for %s, resorting to local user lookup: %s",
    664                                   principal_string, smb_get_krb5_error_message(context,
    665                                                      ret, mem_ctx)));
    666                         nt_status = gensec_security->auth_context->get_user_info_dc_principal(mem_ctx,
    667                                                                                              gensec_security->auth_context,
    668                                                                                              principal_string,
    669                                                                                              NULL, &user_info_dc);
    670                         if (!NT_STATUS_IS_OK(nt_status)) {
    671                                 free(principal_string);
    672                                 krb5_free_principal(context, client_principal);
    673                                 talloc_free(mem_ctx);
    674                                 return nt_status;
    675                         }
    676                 } else {
    677                         DEBUG(1, ("Unable to find PAC in ticket from %s, failing to allow access\n",
    678                                   principal_string));
     738                                                     ret, tmp_ctx)));
     739        } else {
     740                /* Found pac */
     741                pac_blob = data_blob_talloc(tmp_ctx, pac_data.data, pac_data.length);
     742                kerberos_free_data_contents(context, &pac_data);
     743                if (!pac_blob.data) {
    679744                        free(principal_string);
    680745                        krb5_free_principal(context, client_principal);
    681                         talloc_free(mem_ctx);
    682                         return NT_STATUS_ACCESS_DENIED;
    683                 }
    684         } else {
    685                 /* Found pac */
    686                 union netr_Validation validation;
    687 
    688                 pac = data_blob_talloc(mem_ctx, pac_data.data, pac_data.length);
    689                 if (!pac.data) {
    690                         free(principal_string);
    691                         krb5_free_principal(context, client_principal);
    692                         talloc_free(mem_ctx);
     746                        talloc_free(tmp_ctx);
    693747                        return NT_STATUS_NO_MEMORY;
    694748                }
    695749
    696750                /* decode and verify the pac */
    697                 nt_status = kerberos_pac_logon_info(gensec_krb5_state,
    698                                                     &logon_info, pac,
    699                                                     gensec_krb5_state->smb_krb5_context->krb5_context,
    700                                                     NULL, gensec_krb5_state->keyblock,
    701                                                     client_principal,
    702                                                     gensec_krb5_state->ticket->ticket.authtime, NULL);
     751                nt_status = kerberos_decode_pac(gensec_krb5_state,
     752                                                pac_blob,
     753                                                gensec_krb5_state->smb_krb5_context->krb5_context,
     754                                                NULL, gensec_krb5_state->keyblock,
     755                                                client_principal,
     756                                                gensec_krb5_state->ticket->ticket.authtime, NULL);
    703757
    704758                if (!NT_STATUS_IS_OK(nt_status)) {
    705759                        free(principal_string);
    706760                        krb5_free_principal(context, client_principal);
    707                         talloc_free(mem_ctx);
     761                        talloc_free(tmp_ctx);
    708762                        return nt_status;
    709763                }
    710764
    711                 validation.sam3 = &logon_info->info3;
    712                 nt_status = make_user_info_dc_netlogon_validation(mem_ctx,
    713                                                                  NULL,
    714                                                                  3, &validation,
    715                                                                  &user_info_dc);
    716                 if (!NT_STATUS_IS_OK(nt_status)) {
    717                         free(principal_string);
    718                         krb5_free_principal(context, client_principal);
    719                         talloc_free(mem_ctx);
    720                         return nt_status;
    721                 }
    722         }
     765                pac_blob_ptr = &pac_blob;
     766        }
     767
     768        nt_status = gensec_generate_session_info_pac(tmp_ctx,
     769                                                     gensec_security,
     770                                                     gensec_krb5_state->smb_krb5_context,
     771                                                     pac_blob_ptr, principal_string,
     772                                                     gensec_get_remote_address(gensec_security),
     773                                                     &session_info);
    723774
    724775        free(principal_string);
    725776        krb5_free_principal(context, client_principal);
    726777
    727         /* references the user_info_dc into the session_info */
    728         nt_status = gensec_generate_session_info(mem_ctx, gensec_security, user_info_dc, &session_info);
    729 
    730778        if (!NT_STATUS_IS_OK(nt_status)) {
    731                 talloc_free(mem_ctx);
     779                talloc_free(tmp_ctx);
    732780                return nt_status;
    733781        }
    734782
    735         nt_status = gensec_krb5_session_key(gensec_security, &session_info->session_key);
     783        nt_status = gensec_krb5_session_key(gensec_security, session_info, &session_info->session_key);
    736784
    737785        if (!NT_STATUS_IS_OK(nt_status)) {
    738                 talloc_free(mem_ctx);
     786                talloc_free(tmp_ctx);
    739787                return nt_status;
    740788        }
    741789
    742         *_session_info = session_info;
    743 
    744         talloc_steal(gensec_krb5_state, session_info);
    745         talloc_free(mem_ctx);
     790        *_session_info = talloc_steal(mem_ctx, session_info);
     791
     792        talloc_free(tmp_ctx);
    746793        return NT_STATUS_OK;
    747794}
     
    836883        .server_start   = gensec_fake_gssapi_krb5_server_start,
    837884        .update         = gensec_krb5_update,
    838         .magic          = gensec_fake_gssapi_krb5_magic,
     885        .magic          = gensec_magic_check_krb5_oid,
    839886        .session_key    = gensec_krb5_session_key,
    840887        .session_info   = gensec_krb5_session_info,
     
    874921        if (!NT_STATUS_IS_OK(ret)) {
    875922                DEBUG(0,("Failed to register '%s' gensec backend!\n",
    876                         gensec_krb5_security_ops.name));
     923                        gensec_fake_gssapi_krb5_security_ops.name));
    877924                return ret;
    878925        }
  • vendor/current/source4/auth/gensec/gensec_tstream.c

    r740 r988  
    2828#include "lib/tsocket/tsocket.h"
    2929#include "lib/tsocket/tsocket_internal.h"
    30 
     30#include "auth/gensec/gensec_toplevel_proto.h"
    3131
    3232static const struct tstream_context_ops tstream_gensec_ops;
     
    248248                vector[0].iov_len = sizeof(state->wrapped.hdr);
    249249        } else if (!state->wrapped.asked_for_blob) {
     250                uint32_t msg_len;
     251
    250252                state->wrapped.asked_for_blob = true;
    251                 uint32_t msg_len;
    252253
    253254                msg_len = RIVAL(state->wrapped.hdr, 0);
    254255
    255                 if (msg_len > 0x00FFFFFF) {
     256                /*
     257                 * I got a Windows 2012R2 server responding with
     258                 * a message of 0x1b28a33.
     259                 */
     260                if (msg_len > 0x0FFFFFFF) {
    256261                        errno = EMSGSIZE;
    257262                        return -1;
  • vendor/current/source4/auth/gensec/pygensec.c

    r740 r988  
    2121#include "param/pyparam.h"
    2222#include "auth/gensec/gensec.h"
     23#include "auth/gensec/gensec_internal.h" /* TODO: remove this */
    2324#include "auth/credentials/pycredentials.h"
    2425#include "libcli/util/pyerrors.h"
    25 #include "scripting/python/modules.h"
    26 #include "lib/talloc/pytalloc.h"
     26#include "python/modules.h"
     27#include <pytalloc.h>
    2728#include <tevent.h>
    2829#include "librpc/rpc/pyrpc_util.h"
     
    3738                return NULL;
    3839
    39         security = py_talloc_get_type(self, struct gensec_security);
     40        security = pytalloc_get_type(self, struct gensec_security);
    4041
    4142        name = gensec_get_name_by_authtype(security, type);
     
    7980{
    8081        NTSTATUS status;
    81         py_talloc_Object *self;
     82        PyObject *self;
    8283        struct gensec_settings *settings;
    8384        const char *kwnames[] = { "settings", NULL };
    84         PyObject *py_settings;
    85         struct tevent_context *ev;
     85        PyObject *py_settings = Py_None;
    8686        struct gensec_security *gensec;
     87        TALLOC_CTX *frame;
    8788
    8889        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", discard_const_p(char *, kwnames), &py_settings))
    8990                return NULL;
    9091
    91         self = (py_talloc_Object*)type->tp_alloc(type, 0);
    92         if (self == NULL) {
    93                 PyErr_NoMemory();
    94                 return NULL;
    95         }
    96         self->talloc_ctx = talloc_new(NULL);
    97         if (self->talloc_ctx == NULL) {
    98                 PyErr_NoMemory();
    99                 return NULL;
    100         }
     92        frame = talloc_stackframe();
    10193
    10294        if (py_settings != Py_None) {
    103                 settings = settings_from_object(self->talloc_ctx, py_settings);
     95                settings = settings_from_object(frame, py_settings);
    10496                if (settings == NULL) {
    105                         PyObject_DEL(self);
     97                        PyErr_NoMemory();
     98                        TALLOC_FREE(frame);
    10699                        return NULL;
    107100                }
    108101        } else {
    109                 settings = talloc_zero(self->talloc_ctx, struct gensec_settings);
     102                settings = talloc_zero(frame, struct gensec_settings);
    110103                if (settings == NULL) {
    111                         PyObject_DEL(self);
     104                        PyErr_NoMemory();
     105                        TALLOC_FREE(frame);
    112106                        return NULL;
    113107                }
    114108
    115109                settings->lp_ctx = loadparm_init_global(true);
    116         }
    117 
    118         ev = tevent_context_init(self->talloc_ctx);
    119         if (ev == NULL) {
    120                 PyErr_NoMemory();
    121                 PyObject_Del(self);
    122                 return NULL;
    123         }
    124 
    125         status = gensec_init(settings->lp_ctx);
    126         if (!NT_STATUS_IS_OK(status)) {
    127                 PyErr_SetNTSTATUS(status);
    128                 PyObject_DEL(self);
    129                 return NULL;
    130         }
    131 
    132         status = gensec_client_start(self->talloc_ctx, &gensec, ev, settings);
    133         if (!NT_STATUS_IS_OK(status)) {
    134                 PyErr_SetNTSTATUS(status);
    135                 PyObject_DEL(self);
    136                 return NULL;
    137         }
    138 
    139         self->ptr = gensec;
     110                if (settings->lp_ctx == NULL) {
     111                        PyErr_NoMemory();
     112                        TALLOC_FREE(frame);
     113                        return NULL;
     114                }
     115        }
     116
     117        status = gensec_init();
     118        if (!NT_STATUS_IS_OK(status)) {
     119                PyErr_SetNTSTATUS(status);
     120                TALLOC_FREE(frame);
     121                return NULL;
     122        }
     123
     124        status = gensec_client_start(frame, &gensec, settings);
     125        if (!NT_STATUS_IS_OK(status)) {
     126                PyErr_SetNTSTATUS(status);
     127                TALLOC_FREE(frame);
     128                return NULL;
     129        }
     130
     131        self = pytalloc_steal(type, gensec);
     132        TALLOC_FREE(frame);
    140133
    141134        return (PyObject *)self;
     
    145138{
    146139        NTSTATUS status;
    147         py_talloc_Object *self;
     140        PyObject *self;
    148141        struct gensec_settings *settings = NULL;
    149142        const char *kwnames[] = { "settings", "auth_context", NULL };
    150143        PyObject *py_settings = Py_None;
    151144        PyObject *py_auth_context = Py_None;
    152         struct tevent_context *ev;
    153145        struct gensec_security *gensec;
    154         struct auth_context *auth_context = NULL;
     146        struct auth4_context *auth_context = NULL;
     147        TALLOC_CTX *frame;
    155148
    156149        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OO", discard_const_p(char *, kwnames), &py_settings, &py_auth_context))
    157150                return NULL;
    158151
    159         self = (py_talloc_Object*)type->tp_alloc(type, 0);
    160         if (self == NULL) {
    161                 PyErr_NoMemory();
    162                 return NULL;
    163         }
    164         self->talloc_ctx = talloc_new(NULL);
    165         if (self->talloc_ctx == NULL) {
    166                 PyErr_NoMemory();
    167                 return NULL;
    168         }
     152        frame = talloc_stackframe();
    169153
    170154        if (py_settings != Py_None) {
    171                 settings = settings_from_object(self->talloc_ctx, py_settings);
     155                settings = settings_from_object(frame, py_settings);
    172156                if (settings == NULL) {
    173                         PyObject_DEL(self);
     157                        PyErr_NoMemory();
     158                        TALLOC_FREE(frame);
    174159                        return NULL;
    175160                }
    176161        } else {
    177                 settings = talloc_zero(self->talloc_ctx, struct gensec_settings);
     162                settings = talloc_zero(frame, struct gensec_settings);
    178163                if (settings == NULL) {
    179                         PyObject_DEL(self);
     164                        PyErr_NoMemory();
     165                        TALLOC_FREE(frame);
    180166                        return NULL;
    181167                }
    182168
    183169                settings->lp_ctx = loadparm_init_global(true);
    184         }
    185 
    186         ev = tevent_context_init(self->talloc_ctx);
    187         if (ev == NULL) {
    188                 PyErr_NoMemory();
    189                 PyObject_Del(self);
    190                 return NULL;
     170                if (settings->lp_ctx == NULL) {
     171                        PyErr_NoMemory();
     172                        TALLOC_FREE(frame);
     173                        return NULL;
     174                }
    191175        }
    192176
    193177        if (py_auth_context != Py_None) {
    194                 auth_context = py_talloc_get_type(py_auth_context, struct auth_context);
     178                auth_context = pytalloc_get_type(py_auth_context, struct auth4_context);
    195179                if (!auth_context) {
    196180                        PyErr_Format(PyExc_TypeError,
    197181                                     "Expected auth.AuthContext for auth_context argument, got %s",
    198                                      talloc_get_name(py_talloc_get_ptr(py_auth_context)));
     182                                     talloc_get_name(pytalloc_get_ptr(py_auth_context)));
    199183                        return NULL;
    200184                }
    201185        }
    202186
    203         status = gensec_init(settings->lp_ctx);
    204         if (!NT_STATUS_IS_OK(status)) {
    205                 PyErr_SetNTSTATUS(status);
    206                 PyObject_DEL(self);
    207                 return NULL;
    208         }
    209 
    210         status = gensec_server_start(self->talloc_ctx, ev, settings, auth_context, &gensec);
    211         if (!NT_STATUS_IS_OK(status)) {
    212                 PyErr_SetNTSTATUS(status);
    213                 PyObject_DEL(self);
    214                 return NULL;
    215         }
    216 
    217         self->ptr = gensec;
    218 
    219         return (PyObject *)self;
     187        status = gensec_init();
     188        if (!NT_STATUS_IS_OK(status)) {
     189                PyErr_SetNTSTATUS(status);
     190                TALLOC_FREE(frame);
     191                return NULL;
     192        }
     193
     194        status = gensec_server_start(frame, settings, auth_context, &gensec);
     195        if (!NT_STATUS_IS_OK(status)) {
     196                PyErr_SetNTSTATUS(status);
     197                TALLOC_FREE(frame);
     198                return NULL;
     199        }
     200
     201        self = pytalloc_steal(type, gensec);
     202        TALLOC_FREE(frame);
     203
     204        return self;
     205}
     206
     207static PyObject *py_gensec_set_target_hostname(PyObject *self, PyObject *args)
     208{
     209        struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
     210        char *target_hostname;
     211        NTSTATUS status;
     212
     213        if (!PyArg_ParseTuple(args, "s", &target_hostname))
     214                return NULL;
     215
     216        status = gensec_set_target_hostname(security, target_hostname);
     217        if (!NT_STATUS_IS_OK(status)) {
     218                PyErr_SetNTSTATUS(status);
     219                return NULL;
     220        }
     221       
     222        Py_RETURN_NONE;
     223}
     224
     225static PyObject *py_gensec_set_target_service(PyObject *self, PyObject *args)
     226{
     227        struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
     228        char *target_service;
     229        NTSTATUS status;
     230
     231        if (!PyArg_ParseTuple(args, "s", &target_service))
     232                return NULL;
     233
     234        status = gensec_set_target_service(security, target_service);
     235        if (!NT_STATUS_IS_OK(status)) {
     236                PyErr_SetNTSTATUS(status);
     237                return NULL;
     238        }
     239       
     240        Py_RETURN_NONE;
    220241}
    221242
     
    224245        PyObject *py_creds = Py_None;
    225246        struct cli_credentials *creds;
    226         struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     247        struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
    227248        NTSTATUS status;
    228249
     
    234255                PyErr_Format(PyExc_TypeError,
    235256                             "Expected samba.credentaials for credentials argument got  %s",
    236                              talloc_get_name(py_talloc_get_ptr(py_creds)));
     257                             talloc_get_name(pytalloc_get_ptr(py_creds)));
    237258        }
    238259
     
    248269static PyObject *py_gensec_session_info(PyObject *self)
    249270{
     271        TALLOC_CTX *mem_ctx;
    250272        NTSTATUS status;
    251273        PyObject *py_session_info;
    252         struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     274        struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
    253275        struct auth_session_info *info;
    254276        if (security->ops == NULL) {
     
    256278                return NULL;
    257279        }
    258         status = gensec_session_info(security, &info);
     280        mem_ctx = talloc_new(NULL);
     281
     282        status = gensec_session_info(security, mem_ctx, &info);
    259283        if (NT_STATUS_IS_ERR(status)) {
    260284                PyErr_SetNTSTATUS(status);
     
    262286        }
    263287
    264         py_session_info = py_return_ndr_struct("samba.auth", "AuthSession",
     288        py_session_info = py_return_ndr_struct("samba.dcerpc.auth", "session_info",
    265289                                                 info, info);
     290        talloc_free(mem_ctx);
    266291        return py_session_info;
    267292}
    268293
     294static PyObject *py_gensec_session_key(PyObject *self)
     295{
     296        TALLOC_CTX *mem_ctx;
     297        NTSTATUS status;
     298        struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
     299        DATA_BLOB session_key = data_blob_null;
     300        static PyObject *session_key_obj = NULL;
     301
     302        if (security->ops == NULL) {
     303                PyErr_SetString(PyExc_RuntimeError, "no mechanism selected");
     304                return NULL;
     305        }
     306        mem_ctx = talloc_new(NULL);
     307
     308        status = gensec_session_key(security, mem_ctx, &session_key);
     309        if (!NT_STATUS_IS_OK(status)) {
     310                talloc_free(mem_ctx);
     311                PyErr_SetNTSTATUS(status);
     312                return NULL;
     313        }
     314
     315        session_key_obj = PyString_FromStringAndSize((const char *)session_key.data,
     316                                                     session_key.length);
     317        talloc_free(mem_ctx);
     318        return session_key_obj;
     319}
     320
    269321static PyObject *py_gensec_start_mech_by_name(PyObject *self, PyObject *args)
    270322{
    271323        char *name;
    272         struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     324        struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
    273325        NTSTATUS status;
    274326
     
    288340{
    289341        char *sasl_name;
    290         struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     342        struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
    291343        NTSTATUS status;
    292344
     
    306358{
    307359        int authtype, level;
    308         struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     360        struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
    309361        NTSTATUS status;
    310362        if (!PyArg_ParseTuple(args, "ii", &authtype, &level))
     
    323375{
    324376        int feature;
    325         struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     377        struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
    326378        /* This is i (and declared as an int above) by design, as they are handled as an integer in python */
    327379        if (!PyArg_ParseTuple(args, "i", &feature))
     
    336388{
    337389        int feature;
    338         struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     390        struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
    339391        /* This is i (and declared as an int above) by design, as they are handled as an integer in python */
    340392        if (!PyArg_ParseTuple(args, "i", &feature))
     
    347399}
    348400
     401static PyObject *py_gensec_set_max_update_size(PyObject *self, PyObject *args)
     402{
     403        struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
     404        unsigned int max_update_size = 0;
     405
     406        if (!PyArg_ParseTuple(args, "I", &max_update_size))
     407                return NULL;
     408
     409        gensec_set_max_update_size(security, max_update_size);
     410
     411        Py_RETURN_NONE;
     412}
     413
     414static PyObject *py_gensec_max_update_size(PyObject *self)
     415{
     416        struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
     417        unsigned int max_update_size = gensec_max_update_size(security);
     418
     419        return PyInt_FromLong(max_update_size);
     420}
     421
    349422static PyObject *py_gensec_update(PyObject *self, PyObject *args)
    350423{
     
    353426        DATA_BLOB in, out;
    354427        PyObject *ret, *py_in;
    355         struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     428        struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
    356429        PyObject *finished_processing;
    357430
     
    396469        DATA_BLOB in, out;
    397470        PyObject *ret, *py_in;
    398         struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     471        struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
    399472
    400473        if (!PyArg_ParseTuple(args, "O", &py_in))
     
    430503        DATA_BLOB in, out;
    431504        PyObject *ret, *py_in;
    432         struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     505        struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
    433506
    434507        if (!PyArg_ParseTuple(args, "O", &py_in))
     
    456529        talloc_free(mem_ctx);
    457530        return ret;
     531}
     532
     533static PyObject *py_gensec_sig_size(PyObject *self, PyObject *args)
     534{
     535        struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
     536        Py_ssize_t data_size = 0;
     537        size_t sig_size = 0;
     538
     539        if (!PyArg_ParseTuple(args, "n", &data_size)) {
     540                return NULL;
     541        }
     542
     543        sig_size = gensec_sig_size(security, data_size);
     544
     545        return PyLong_FromSize_t(sig_size);
     546}
     547
     548static PyObject *py_gensec_sign_packet(PyObject *self, PyObject *args)
     549{
     550        NTSTATUS status;
     551        TALLOC_CTX *mem_ctx = NULL;
     552        Py_ssize_t data_length = 0;
     553        Py_ssize_t pdu_length = 0;
     554        DATA_BLOB data, pdu, sig;
     555        PyObject *py_sig;
     556        struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
     557
     558        if (!PyArg_ParseTuple(args, "z#z#", &data.data, &data_length, &pdu.data, &pdu_length)) {
     559                return NULL;
     560        }
     561        data.length = data_length;
     562        pdu.length = pdu_length;
     563
     564        mem_ctx = talloc_new(NULL);
     565
     566        status = gensec_sign_packet(security, mem_ctx,
     567                                    data.data, data.length,
     568                                    pdu.data, pdu.length, &sig);
     569        if (!NT_STATUS_IS_OK(status)) {
     570                PyErr_SetNTSTATUS(status);
     571                talloc_free(mem_ctx);
     572                return NULL;
     573        }
     574
     575        py_sig = PyBytes_FromStringAndSize((const char *)sig.data, sig.length);
     576        talloc_free(mem_ctx);
     577        return py_sig;
     578}
     579
     580static PyObject *py_gensec_check_packet(PyObject *self, PyObject *args)
     581{
     582        NTSTATUS status;
     583        Py_ssize_t data_length = 0;
     584        Py_ssize_t pdu_length = 0;
     585        Py_ssize_t sig_length = 0;
     586        DATA_BLOB data, pdu, sig;
     587        struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
     588
     589        if (!PyArg_ParseTuple(args, "z#z#z#",
     590                              &data.data, &data_length,
     591                              &pdu.data, &pdu_length,
     592                              &sig.data, &sig_length)) {
     593                return NULL;
     594        }
     595        data.length = data_length;
     596        pdu.length = pdu_length;
     597        sig.length = sig_length;
     598
     599        status = gensec_check_packet(security,
     600                                     data.data, data.length,
     601                                     pdu.data, pdu.length, &sig);
     602        if (!NT_STATUS_IS_OK(status)) {
     603                PyErr_SetNTSTATUS(status);
     604                return NULL;
     605        }
     606
     607        Py_RETURN_NONE;
    458608}
    459609
     
    465615        { "set_credentials", (PyCFunction)py_gensec_set_credentials, METH_VARARGS,
    466616                "S.start_client(credentials)" },
     617        { "set_target_hostname", (PyCFunction)py_gensec_set_target_hostname, METH_VARARGS,
     618                "S.start_target_hostname(target_hostname)" },
     619        { "set_target_service", (PyCFunction)py_gensec_set_target_service, METH_VARARGS,
     620                "S.start_target_service(target_service)" },
    467621        { "session_info", (PyCFunction)py_gensec_session_info, METH_NOARGS,
    468                 "S.session_info() -> info" },
     622                "S.session_info() -> info" },
     623        { "session_key", (PyCFunction)py_gensec_session_key, METH_NOARGS,
     624                "S.session_key() -> key" },
    469625        { "start_mech_by_name", (PyCFunction)py_gensec_start_mech_by_name, METH_VARARGS,
    470         "S.start_mech_by_name(name)" },
     626                "S.start_mech_by_name(name)" },
    471627        { "start_mech_by_sasl_name", (PyCFunction)py_gensec_start_mech_by_sasl_name, METH_VARARGS,
    472         "S.start_mech_by_sasl_name(name)" },
    473         { "start_mech_by_authtype", (PyCFunction)py_gensec_start_mech_by_authtype, METH_VARARGS, "S.start_mech_by_authtype(authtype, level)" },
     628                "S.start_mech_by_sasl_name(name)" },
     629        { "start_mech_by_authtype", (PyCFunction)py_gensec_start_mech_by_authtype, METH_VARARGS,
     630                "S.start_mech_by_authtype(authtype, level)" },
    474631        { "get_name_by_authtype", (PyCFunction)py_get_name_by_authtype, METH_VARARGS,
    475632                "S.get_name_by_authtype(authtype) -> name\nLookup an auth type." },
    476633        { "want_feature", (PyCFunction)py_gensec_want_feature, METH_VARARGS,
    477           "S.want_feature(feature)\n Request that GENSEC negotiate a particular feature." },
     634                "S.want_feature(feature)\n Request that GENSEC negotiate a particular feature." },
    478635        { "have_feature", (PyCFunction)py_gensec_have_feature, METH_VARARGS,
    479           "S.have_feature()\n Return True if GENSEC negotiated a particular feature." },
     636                "S.have_feature()\n Return True if GENSEC negotiated a particular feature." },
     637        { "set_max_update_size",  (PyCFunction)py_gensec_set_max_update_size, METH_VARARGS,
     638                "S.set_max_update_size(max_size) \n Some mechs can fragment update packets, needs to be use before the mech is started." },
     639        { "max_update_size",  (PyCFunction)py_gensec_max_update_size, 0,
     640                "S.max_update_size() \n Return the current max_update_size." },
    480641        { "update",  (PyCFunction)py_gensec_update, METH_VARARGS,
    481642                "S.update(blob_in) -> (finished, blob_out)\nPerform one step in a GENSEC dance.  Repeat with new packets until finished is true or exception." },
     
    484645        { "unwrap",  (PyCFunction)py_gensec_unwrap, METH_VARARGS,
    485646                "S.unwrap(blob_in) -> blob_out\nPerform one wrapped GENSEC packet into a clear packet." },
    486 
     647        { "sig_size",  (PyCFunction)py_gensec_sig_size, METH_VARARGS,
     648                "S.sig_size(data_size) -> sig_size\nSize of the DCERPC packet signature" },
     649        { "sign_packet",  (PyCFunction)py_gensec_sign_packet, METH_VARARGS,
     650                "S.sign_packet(data, whole_pdu) -> sig\nSign a DCERPC packet." },
     651        { "check_packet",  (PyCFunction)py_gensec_check_packet, METH_VARARGS,
     652                "S.check_packet(data, whole_pdu, sig)\nCheck a DCERPC packet." },
    487653        { NULL }
    488654};
    489655
    490656static PyTypeObject Py_Security = {
    491         .tp_name = "Security",
     657        .tp_name = "gensec.Security",
    492658        .tp_flags = Py_TPFLAGS_DEFAULT,
    493659        .tp_methods = py_gensec_security_methods,
    494         .tp_basicsize = sizeof(py_talloc_Object),
    495660};
    496661
     
    500665        PyObject *m;
    501666
    502         Py_Security.tp_base = PyTalloc_GetObjectType();
    503         if (Py_Security.tp_base == NULL)
    504                 return;
    505 
    506         if (PyType_Ready(&Py_Security) < 0)
     667        if (pytalloc_BaseObject_PyType_Ready(&Py_Security) < 0)
    507668                return;
    508669
  • vendor/current/source4/auth/gensec/wscript_build

    r740 r988  
    11#!/usr/bin/env python
    22
    3 bld.SAMBA_LIBRARY('gensec',
    4         source='gensec.c socket.c gensec_tstream.c',
    5         pc_files='gensec.pc',
    6         autoproto='gensec_proto.h',
    7         public_deps='UTIL_TEVENT samba-util errors LIBPACKET auth_system_session',
    8         public_headers='gensec.h',
    9         deps='com_err',
    10         vnum='0.0.1'
    11         )
     3bld.SAMBA_SUBSYSTEM('gensec_util',
     4                    source='gensec_tstream.c',
     5                    deps='tevent-util tevent samba-util LIBTSOCKET',
     6                    autoproto='gensec_proto.h')
    127
    138bld.SAMBA_MODULE('gensec_krb5',
    14         source='gensec_krb5.c',
     9        source='gensec_krb5.c gensec_krb5_util.c',
    1510        subsystem='gensec',
    1611        init_function='gensec_krb5_init',
    17         deps='credentials authkrb5 auth_session com_err',
     12        deps='samba-credentials authkrb5 com_err gensec_util',
    1813        internal_module=False,
     14        enabled=bld.AD_DC_BUILD_IS_ENABLED() and bld.CONFIG_SET('SAMBA4_USES_HEIMDAL')
    1915        )
    2016
     
    2420        subsystem='gensec',
    2521        init_function='gensec_gssapi_init',
    26         deps='gssapi credentials authkrb5 com_err'
     22        deps='gssapi samba-credentials authkrb5 com_err gensec_util'
    2723        )
    28 
    29 
    30 bld.SAMBA_MODULE('cyrus_sasl',
    31         source='cyrus_sasl.c',
    32         subsystem='gensec',
    33         init_function='gensec_sasl_init',
    34         deps='credentials sasl2',
    35         enabled=bld.CONFIG_SET('HAVE_SASL')
    36         )
    37 
    38 
    39 bld.SAMBA_MODULE('gensec_spnego',
    40         source='spnego.c',
    41         autoproto='spnego_proto.h',
    42         subsystem='gensec',
    43         init_function='gensec_spnego_init',
    44         deps='ASN1_UTIL credentials SPNEGO_PARSE'
    45         )
    46 
    47 
    48 bld.SAMBA_MODULE('gensec_schannel',
    49         source='schannel.c',
    50         subsystem='gensec',
    51         deps='COMMON_SCHANNEL NDR_SCHANNEL credentials ndr auth_session',
    52         internal_module=True,
    53         autoproto='schannel_proto.h',
    54         init_function='gensec_schannel_init'
    55         )
    56 
    5724
    5825bld.SAMBA_PYTHON('pygensec',
Note: See TracChangeset for help on using the changeset viewer.