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
Files:
4 added
17 deleted
32 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source4/auth/auth.h

    r740 r988  
    4444/* version 4 - subsequent samba4 version - metze */
    4545/* version 0 - till samba4 is stable - metze */
    46 #define AUTH_INTERFACE_VERSION 0
    47 
    48 #define AUTH_SESSION_INFO_DEFAULT_GROUPS     0x01 /* Add the user to the default world and network groups */
    49 #define AUTH_SESSION_INFO_AUTHENTICATED      0x02 /* Add the user to the 'authenticated users' group */
    50 #define AUTH_SESSION_INFO_SIMPLE_PRIVILEGES  0x04 /* Use a trivial map between users and privilages, rather than a DB */
     46#define AUTH4_INTERFACE_VERSION 0
    5147
    5248struct auth_method_context;
    5349struct auth_check_password_request;
    54 struct auth_context;
     50struct auth4_context;
    5551struct auth_session_info;
    5652struct ldb_dn;
     53struct smb_krb5_context;
    5754
    5855struct auth_operations {
    5956        const char *name;
    60 
    61         /* If you are using this interface, then you are probably
    62          * getting something wrong.  This interface is only for
    63          * security=server, and makes a number of compromises to allow
    64          * that.  It is not compatible with being a PDC.  */
    65 
    66         NTSTATUS (*get_challenge)(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, uint8_t chal[8]);
    6757
    6858        /* Given the user supplied info, check if this backend want to handle the password checking */
     
    7969        /* Lookup a 'session info interim' return based only on the principal or DN */
    8070        NTSTATUS (*get_user_info_dc_principal)(TALLOC_CTX *mem_ctx,
    81                                                        struct auth_context *auth_context,
     71                                                       struct auth4_context *auth_context,
    8272                                                       const char *principal,
    8373                                                       struct ldb_dn *user_dn,
    8474                                                       struct auth_user_info_dc **interim_info);
     75        uint32_t flags;
    8576};
    8677
    8778struct auth_method_context {
    8879        struct auth_method_context *prev, *next;
    89         struct auth_context *auth_ctx;
     80        struct auth4_context *auth_ctx;
    9081        const struct auth_operations *ops;
    9182        int depth;
    9283        void *private_data;
    93 };
    94 
    95 struct auth_context {
    96         struct {
    97                 /* Who set this up in the first place? */
    98                 const char *set_by;
    99 
    100                 bool may_be_modified;
    101 
    102                 DATA_BLOB data;
    103         } challenge;
    104 
    105         /* methods, in the order they should be called */
    106         struct auth_method_context *methods;
    107 
    108         /* the event context to use for calls that can block */
    109         struct tevent_context *event_ctx;
    110 
    111         /* the messaging context which can be used by backends */
    112         struct messaging_context *msg_ctx;
    113 
    114         /* loadparm context */
    115         struct loadparm_context *lp_ctx;
    116 
    117         /* SAM database for this local machine - to fill in local groups, or to authenticate local NTLM users */
    118         struct ldb_context *sam_ctx;
    119 
    120         NTSTATUS (*check_password)(struct auth_context *auth_ctx,
    121                                    TALLOC_CTX *mem_ctx,
    122                                    const struct auth_usersupplied_info *user_info,
    123                                    struct auth_user_info_dc **user_info_dc);
    124 
    125         NTSTATUS (*get_challenge)(struct auth_context *auth_ctx, uint8_t chal[8]);
    126 
    127         bool (*challenge_may_be_modified)(struct auth_context *auth_ctx);
    128 
    129         NTSTATUS (*set_challenge)(struct auth_context *auth_ctx, const uint8_t chal[8], const char *set_by);
    130 
    131         NTSTATUS (*get_user_info_dc_principal)(TALLOC_CTX *mem_ctx,
    132                                                        struct auth_context *auth_ctx,
    133                                                        const char *principal,
    134                                                        struct ldb_dn *user_dn,
    135                                                        struct auth_user_info_dc **user_info_dc);
    136 
    137         NTSTATUS (*generate_session_info)(TALLOC_CTX *mem_ctx,
    138                                           struct auth_context *auth_context,
    139                                           struct auth_user_info_dc *user_info_dc,
    140                                           uint32_t session_info_flags,
    141                                           struct auth_session_info **session_info);
    14284};
    14385
     
    15294};
    15395
    154  NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth_context *auth_context,
     96 NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth4_context *auth_context,
    15597                           enum auth_password_state to_state,
    15698                           const struct auth_usersupplied_info *user_info_in,
     
    158100
    159101#include "auth/session.h"
     102#include "auth/unix_token_proto.h"
    160103#include "auth/system_session_proto.h"
    161104#include "libcli/security/security.h"
     
    166109struct cli_credentials;
    167110
    168 NTSTATUS auth_get_challenge(struct auth_context *auth_ctx, uint8_t chal[8]);
     111NTSTATUS auth_get_challenge(struct auth4_context *auth_ctx, uint8_t chal[8]);
    169112NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx,
    170113                            struct ldb_context *sam_ctx,
     
    176119                            bool allow_domain_trust,
    177120                            bool password_change);
    178 NTSTATUS authsam_expand_nested_groups(struct ldb_context *sam_ctx,
    179                                       struct ldb_val *dn_val, const bool only_childs, const char *filter,
    180                                       TALLOC_CTX *res_sids_ctx, struct dom_sid ***res_sids,
    181                                       unsigned int *num_res_sids);
     121
    182122struct auth_session_info *system_session(struct loadparm_context *lp_ctx);
    183123NTSTATUS authsam_make_user_info_dc(TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx,
     
    192132                                           struct auth_session_info **_session_info) ;
    193133
    194 NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char **methods,
     134NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char * const *methods,
    195135                                     struct tevent_context *ev,
    196                                      struct messaging_context *msg,
     136                                     struct imessaging_context *msg,
    197137                                     struct loadparm_context *lp_ctx,
    198138                                     struct ldb_context *sam_ctx,
    199                                      struct auth_context **auth_ctx);
     139                                     struct auth4_context **auth_ctx);
    200140const char **auth_methods_from_lp(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx);
    201141
    202142NTSTATUS auth_context_create(TALLOC_CTX *mem_ctx,
    203143                             struct tevent_context *ev,
    204                              struct messaging_context *msg,
     144                             struct imessaging_context *msg,
    205145                             struct loadparm_context *lp_ctx,
    206                              struct auth_context **auth_ctx);
    207 NTSTATUS auth_context_create_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct auth_context **auth_ctx);
     146                             struct auth4_context **auth_ctx);
    208147
    209 NTSTATUS auth_check_password(struct auth_context *auth_ctx,
     148NTSTATUS auth_check_password_wrapper(struct auth4_context *auth_ctx,
    210149                             TALLOC_CTX *mem_ctx,
    211                              const struct auth_usersupplied_info *user_info,
     150                             const struct auth_usersupplied_info *user_info,
     151                             void **server_returned_info,
     152                             DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key);
     153
     154NTSTATUS auth_check_password(struct auth4_context *auth_ctx,
     155                             TALLOC_CTX *mem_ctx,
     156                             const struct auth_usersupplied_info *user_info,
    212157                             struct auth_user_info_dc **user_info_dc);
    213158NTSTATUS auth4_init(void);
     
    216161NTSTATUS authenticate_username_pw(TALLOC_CTX *mem_ctx,
    217162                                  struct tevent_context *ev,
    218                                   struct messaging_context *msg,
     163                                  struct imessaging_context *msg,
    219164                                  struct loadparm_context *lp_ctx,
    220165                                  const char *nt4_domain,
     
    226171struct tevent_req *auth_check_password_send(TALLOC_CTX *mem_ctx,
    227172                                            struct tevent_context *ev,
    228                                             struct auth_context *auth_ctx,
     173                                            struct auth4_context *auth_ctx,
    229174                                            const struct auth_usersupplied_info *user_info);
    230175NTSTATUS auth_check_password_recv(struct tevent_req *req,
     
    232177                                  struct auth_user_info_dc **user_info_dc);
    233178
    234 bool auth_challenge_may_be_modified(struct auth_context *auth_ctx);
    235 NTSTATUS auth_context_set_challenge(struct auth_context *auth_ctx, const uint8_t chal[8], const char *set_by);
     179bool auth_challenge_may_be_modified(struct auth4_context *auth_ctx);
     180NTSTATUS auth_context_set_challenge(struct auth4_context *auth_ctx, const uint8_t chal[8], const char *set_by);
    236181
    237182NTSTATUS auth_get_user_info_dc_principal(TALLOC_CTX *mem_ctx,
    238                                         struct auth_context *auth_ctx,
     183                                        struct auth4_context *auth_ctx,
    239184                                        const char *principal,
    240185                                        struct ldb_dn *user_dn,
     
    243188NTSTATUS samba_server_gensec_start(TALLOC_CTX *mem_ctx,
    244189                                   struct tevent_context *event_ctx,
    245                                    struct messaging_context *msg_ctx,
     190                                   struct imessaging_context *msg_ctx,
    246191                                   struct loadparm_context *lp_ctx,
    247192                                   struct cli_credentials *server_credentials,
  • 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',
  • vendor/current/source4/auth/kerberos/kerberos-notes.txt

    r414 r988  
    77------------------------------------
    88
    9 This document should be read in conjuction with the Samba4 source code. 
     9This document should be read in conjunction with the Samba4 source code. 
    1010DAL and KDC requirements are expressed (as an implementation against Heimdal's
    1111HDB abstraction layer) in Samba4's source4/kdc/hdb-samba4.c in particular.
     
    160160correctly implement the GSSAPI specification, particularly on top of the
    161161(inflexible) MIT Kerberos API.  It did not seem possible to write a correct,
    162 seperate GSSAPI implementation on top of MIT Kerberos's public krb5lib API,
     162separate GSSAPI implementation on top of MIT Kerberos's public krb5lib API,
    163163and at the time, the effort did not need to extend beyond what Windows would
    164164require. 
     
    528528
    529529Traditional 'MIT' behaviour is to use a keytab, containing salted key
    530 data, extracted from the KDC.  (In this modal, there is no 'service
     530data, extracted from the KDC.  (In this model, there is no 'service
    531531password', instead the keys are often simply application of random
    532532bytes).  Heimdal also implements this behaviour.
    533533
    534 The windows modal is very different - instead of sharing a keytab with
     534The windows model is very different - instead of sharing a keytab with
    535535each member server, a random utf-16 pseudo-textual password is stored
    536536for the whole machine. 
  • vendor/current/source4/auth/kerberos/kerberos.h

    r740 r988  
    1919*/
    2020
     21#ifndef _AUTH_KERBEROS_H_
     22#define _AUTH_KERBEROS_H_
     23
    2124#if defined(HAVE_KRB5)
    2225
     26#include "system/kerberos.h"
    2327#include "auth/kerberos/krb5_init_context.h"
    2428#include "librpc/gen_ndr/krb5pac.h"
     29#include "lib/krb5_wrap/krb5_samba.h"
     30#include "lib/krb5_wrap/gss_samba.h"
    2531
    2632struct auth_user_info_dc;
     
    3541        struct smb_krb5_context *smb_krb5_context;
    3642        krb5_keytab keytab;
     43        bool password_based;
    3744};
    3845
     
    4451#define TOK_ID_GSS_WRAP         ((const uint8_t *)"\x02\x01")
    4552
    46 #ifdef HAVE_KRB5_KEYBLOCK_KEYVALUE
    47 #define KRB5_KEY_TYPE(k)        ((k)->keytype)
    48 #define KRB5_KEY_LENGTH(k)      ((k)->keyvalue.length)
    49 #define KRB5_KEY_DATA(k)        ((k)->keyvalue.data)
    50 #else
    51 #define KRB5_KEY_TYPE(k)        ((k)->enctype)
    52 #define KRB5_KEY_LENGTH(k)      ((k)->length)
    53 #define KRB5_KEY_DATA(k)        ((k)->contents)
    54 #endif /* HAVE_KRB5_KEYBLOCK_KEYVALUE */
    55 
    5653#define ENC_ALL_TYPES (ENC_CRC32 | ENC_RSA_MD5 | ENC_RC4_HMAC_MD5 |     \
    5754                       ENC_HMAC_SHA1_96_AES128 | ENC_HMAC_SHA1_96_AES256)
    58 
    59 #ifndef HAVE_KRB5_SET_REAL_TIME
    60 krb5_error_code krb5_set_real_time(krb5_context context, int32_t seconds, int32_t microseconds);
    61 #endif
    6255
    6356#ifndef HAVE_KRB5_SET_DEFAULT_TGS_KTYPES
     
    6962#endif
    7063
    71 #ifndef HAVE_KRB5_FREE_UNPARSED_NAME
    72 void krb5_free_unparsed_name(krb5_context ctx, char *val);
    73 #endif
    74 
    7564#if defined(HAVE_KRB5_PRINCIPAL_GET_COMP_STRING) && !defined(HAVE_KRB5_PRINC_COMPONENT)
    7665const krb5_data *krb5_princ_component(krb5_context context, krb5_principal principal, int i );
     
    7867
    7968/* Samba wrapper function for krb5 functionality. */
    80 void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr);
    81 int create_kerberos_key_from_string(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, krb5_enctype enctype);
    82 int create_kerberos_key_from_string_direct(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, krb5_enctype enctype);
    83 krb5_const_principal get_principal_from_tkt(krb5_ticket *tkt);
    84 krb5_error_code get_kerberos_allowed_etypes(krb5_context context, krb5_enctype **enctypes);
    85 void free_kerberos_etypes(krb5_context context, krb5_enctype *enctypes);
    86 bool get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, DATA_BLOB *session_key, bool remote);
    87 krb5_error_code ads_krb5_mk_req(krb5_context context,
    88                                 krb5_auth_context *auth_context,
    89                                 const krb5_flags ap_req_options,
    90                                 const char *principal,
    91                                 krb5_ccache ccache,
    92                                 krb5_data *outbuf);
    93 bool get_auth_data_from_tkt(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, krb5_ticket *tkt);
    94 krb5_error_code kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc,
    95                                            krb5_principal principal, const char *password,
    96                                            krb5_principal impersonate_principal, const char *target_service,
    97                                            krb5_get_init_creds_opt *krb_options,
    98                                            time_t *expire_time, time_t *kdc_time);
    99 krb5_error_code kerberos_kinit_keyblock_cc(krb5_context ctx, krb5_ccache cc,
    100                                            krb5_principal principal, krb5_keyblock *keyblock,
    101                                            const char *target_service,
    102                                            krb5_get_init_creds_opt *krb_options,
    103                                            time_t *expire_time, time_t *kdc_time);
    104 krb5_principal kerberos_fetch_salt_princ_for_host_princ(krb5_context context,
    105                                                         krb5_principal host_princ,
    106                                                         int enctype);
    107 void kerberos_set_creds_enctype(krb5_creds *pcreds, int enctype);
    108 bool kerberos_compatible_enctypes(krb5_context context, krb5_enctype enctype1, krb5_enctype enctype2);
    109 void kerberos_free_data_contents(krb5_context context, krb5_data *pdata);
    110 krb5_error_code smb_krb5_kt_free_entry(krb5_context context, krb5_keytab_entry *kt_entry);
    111 char *smb_get_krb5_error_message(krb5_context context, krb5_error_code code, TALLOC_CTX *mem_ctx);
    112 NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx,
    113                              struct PAC_DATA **pac_data_out,
    114                              DATA_BLOB blob,
    115                              krb5_context context,
    116                              const krb5_keyblock *krbtgt_keyblock,
    117                              const krb5_keyblock *service_keyblock,
    118                              krb5_const_principal client_principal,
    119                              time_t tgs_authtime,
    120                              krb5_error_code *k5ret);
    121  NTSTATUS kerberos_pac_logon_info(TALLOC_CTX *mem_ctx,
    122                                   struct PAC_LOGON_INFO **logon_info,
    123                                   DATA_BLOB blob,
    124                                   krb5_context context,
    125                                   const krb5_keyblock *krbtgt_keyblock,
    126                                   const krb5_keyblock *service_keyblock,
    127                                   krb5_const_principal client_principal,
    128                                   time_t tgs_authtime,
    129                                   krb5_error_code *k5ret);
    13069 krb5_error_code kerberos_encode_pac(TALLOC_CTX *mem_ctx,
    13170                                    struct PAC_DATA *pac_data,
     
    14281                                     time_t tgs_authtime,
    14382                                     DATA_BLOB *pac);
    144 struct loadparm_context;
    145 struct ldb_message;
    146 struct ldb_context;
    147 uint32_t kerberos_enctype_to_bitmap(krb5_enctype enc_type_enum);
    148 /* Translate between the Microsoft msDS-SupportedEncryptionTypes values and the IETF encryption type values */
    149 krb5_enctype kerberos_enctype_bitmap_to_enctype(uint32_t enctype_bitmap);
    150 krb5_error_code smb_krb5_update_keytab(TALLOC_CTX *parent_ctx,
    151                                        struct smb_krb5_context *smb_krb5_context,
    152                                        struct ldb_context *ldb,
    153                                        struct ldb_message *msg,
    154                                        bool delete_all_kvno,
    155                                        const char **error_string);
    15683
    15784#include "auth/kerberos/proto.h"
    15885
    15986#endif /* HAVE_KRB5 */
     87
     88#endif /* _AUTH_KERBEROS_H_ */
  • vendor/current/source4/auth/kerberos/kerberos_credentials.h

    r740 r988  
    2828                                enum credentials_obtained *obtained,
    2929                                const char **error_string);
     30
     31/* Manually prototyped here to avoid needing krb5 headers in most callers */
     32krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx,
     33                                struct cli_credentials *credentials,
     34                                struct smb_krb5_context *smb_krb5_context,
     35                                krb5_principal *princ,
     36                                enum credentials_obtained *obtained,
     37                                const char **error_string);
  • vendor/current/source4/auth/kerberos/kerberos_pac.c

    r740 r988  
    3131#include <ldb.h>
    3232#include "auth/auth_sam_reply.h"
    33 
    34 krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx,
    35                                    DATA_BLOB pac_data,
    36                                    struct PAC_SIGNATURE_DATA *sig,
    37                                    krb5_context context,
    38                                    const krb5_keyblock *keyblock)
    39 {
    40         krb5_error_code ret;
    41         krb5_crypto crypto;
    42         Checksum cksum;
    43 
    44         cksum.cksumtype         = (CKSUMTYPE)sig->type;
    45         cksum.checksum.length   = sig->signature.length;
    46         cksum.checksum.data     = sig->signature.data;
    47 
    48         ret = krb5_crypto_init(context,
    49                                keyblock,
    50                                0,
    51                                &crypto);
    52         if (ret) {
    53                 DEBUG(0,("krb5_crypto_init() failed: %s\n",
    54                           smb_get_krb5_error_message(context, ret, mem_ctx)));
    55                 return ret;
    56         }
    57         ret = krb5_verify_checksum(context,
    58                                    crypto,
    59                                    KRB5_KU_OTHER_CKSUM,
    60                                    pac_data.data,
    61                                    pac_data.length,
    62                                    &cksum);
    63         krb5_crypto_destroy(context, crypto);
    64 
    65         return ret;
    66 }
    67 
    68  NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx,
    69                               struct PAC_DATA **pac_data_out,
    70                               DATA_BLOB blob,
    71                               krb5_context context,
    72                               const krb5_keyblock *krbtgt_keyblock,
    73                               const krb5_keyblock *service_keyblock,
    74                               krb5_const_principal client_principal,
    75                               time_t tgs_authtime,
    76                               krb5_error_code *k5ret)
    77 {
    78         krb5_error_code ret;
    79         NTSTATUS status;
    80         enum ndr_err_code ndr_err;
    81         struct PAC_SIGNATURE_DATA *srv_sig_ptr = NULL;
    82         struct PAC_SIGNATURE_DATA *kdc_sig_ptr = NULL;
    83         struct PAC_SIGNATURE_DATA *srv_sig_wipe = NULL;
    84         struct PAC_SIGNATURE_DATA *kdc_sig_wipe = NULL;
    85         struct PAC_LOGON_INFO *logon_info = NULL;
    86         struct PAC_LOGON_NAME *logon_name = NULL;
    87         struct PAC_DATA *pac_data;
    88         struct PAC_DATA_RAW *pac_data_raw;
    89 
    90         DATA_BLOB *srv_sig_blob = NULL;
    91         DATA_BLOB *kdc_sig_blob = NULL;
    92 
    93         DATA_BLOB modified_pac_blob;
    94         NTTIME tgs_authtime_nttime;
    95         krb5_principal client_principal_pac;
    96         uint32_t i;
    97 
    98         krb5_clear_error_message(context);
    99 
    100         if (k5ret) {
    101                 *k5ret = KRB5_PARSE_MALFORMED;
    102         }
    103 
    104         pac_data = talloc(mem_ctx, struct PAC_DATA);
    105         pac_data_raw = talloc(mem_ctx, struct PAC_DATA_RAW);
    106         kdc_sig_wipe = talloc(mem_ctx, struct PAC_SIGNATURE_DATA);
    107         srv_sig_wipe = talloc(mem_ctx, struct PAC_SIGNATURE_DATA);
    108         if (!pac_data_raw || !pac_data || !kdc_sig_wipe || !srv_sig_wipe) {
    109                 if (k5ret) {
    110                         *k5ret = ENOMEM;
    111                 }
    112                 return NT_STATUS_NO_MEMORY;
    113         }
    114 
    115         ndr_err = ndr_pull_struct_blob(&blob, pac_data,
    116                         pac_data, (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA);
    117         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    118                 status = ndr_map_error2ntstatus(ndr_err);
    119                 DEBUG(0,("can't parse the PAC: %s\n",
    120                         nt_errstr(status)));
    121                 return status;
    122         }
    123 
    124         if (pac_data->num_buffers < 4) {
    125                 /* we need logon_ingo, service_key and kdc_key */
    126                 DEBUG(0,("less than 4 PAC buffers\n"));
    127                 return NT_STATUS_INVALID_PARAMETER;
    128         }
    129 
    130         ndr_err = ndr_pull_struct_blob(&blob, pac_data_raw,
    131                                        pac_data_raw,
    132                                        (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA_RAW);
    133         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    134                 status = ndr_map_error2ntstatus(ndr_err);
    135                 DEBUG(0,("can't parse the PAC: %s\n",
    136                         nt_errstr(status)));
    137                 return status;
    138         }
    139 
    140         if (pac_data_raw->num_buffers < 4) {
    141                 /* we need logon_ingo, service_key and kdc_key */
    142                 DEBUG(0,("less than 4 PAC buffers\n"));
    143                 return NT_STATUS_INVALID_PARAMETER;
    144         }
    145 
    146         if (pac_data->num_buffers != pac_data_raw->num_buffers) {
    147                 /* we need logon_ingo, service_key and kdc_key */
    148                 DEBUG(0,("misparse!  PAC_DATA has %d buffers while PAC_DATA_RAW has %d\n",
    149                          pac_data->num_buffers, pac_data_raw->num_buffers));
    150                 return NT_STATUS_INVALID_PARAMETER;
    151         }
    152 
    153         for (i=0; i < pac_data->num_buffers; i++) {
    154                 if (pac_data->buffers[i].type != pac_data_raw->buffers[i].type) {
    155                         DEBUG(0,("misparse!  PAC_DATA buffer %d has type %d while PAC_DATA_RAW has %d\n",
    156                                  i, pac_data->buffers[i].type, pac_data->buffers[i].type));
    157                         return NT_STATUS_INVALID_PARAMETER;
    158                 }
    159                 switch (pac_data->buffers[i].type) {
    160                         case PAC_TYPE_LOGON_INFO:
    161                                 if (!pac_data->buffers[i].info) {
    162                                         break;
    163                                 }
    164                                 logon_info = pac_data->buffers[i].info->logon_info.info;
    165                                 break;
    166                         case PAC_TYPE_SRV_CHECKSUM:
    167                                 if (!pac_data->buffers[i].info) {
    168                                         break;
    169                                 }
    170                                 srv_sig_ptr = &pac_data->buffers[i].info->srv_cksum;
    171                                 srv_sig_blob = &pac_data_raw->buffers[i].info->remaining;
    172                                 break;
    173                         case PAC_TYPE_KDC_CHECKSUM:
    174                                 if (!pac_data->buffers[i].info) {
    175                                         break;
    176                                 }
    177                                 kdc_sig_ptr = &pac_data->buffers[i].info->kdc_cksum;
    178                                 kdc_sig_blob = &pac_data_raw->buffers[i].info->remaining;
    179                                 break;
    180                         case PAC_TYPE_LOGON_NAME:
    181                                 logon_name = &pac_data->buffers[i].info->logon_name;
    182                                 break;
    183                         default:
    184                                 break;
    185                 }
    186         }
    187 
    188         if (!logon_info) {
    189                 DEBUG(0,("PAC no logon_info\n"));
    190                 return NT_STATUS_INVALID_PARAMETER;
    191         }
    192 
    193         if (!logon_name) {
    194                 DEBUG(0,("PAC no logon_name\n"));
    195                 return NT_STATUS_INVALID_PARAMETER;
    196         }
    197 
    198         if (!srv_sig_ptr || !srv_sig_blob) {
    199                 DEBUG(0,("PAC no srv_key\n"));
    200                 return NT_STATUS_INVALID_PARAMETER;
    201         }
    202 
    203         if (!kdc_sig_ptr || !kdc_sig_blob) {
    204                 DEBUG(0,("PAC no kdc_key\n"));
    205                 return NT_STATUS_INVALID_PARAMETER;
    206         }
    207 
    208         /* Find and zero out the signatures, as required by the signing algorithm */
    209 
    210         /* We find the data blobs above, now we parse them to get at the exact portion we should zero */
    211         ndr_err = ndr_pull_struct_blob(kdc_sig_blob, kdc_sig_wipe,
    212                                        kdc_sig_wipe,
    213                                        (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA);
    214         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    215                 status = ndr_map_error2ntstatus(ndr_err);
    216                 DEBUG(0,("can't parse the KDC signature: %s\n",
    217                         nt_errstr(status)));
    218                 return status;
    219         }
    220 
    221         ndr_err = ndr_pull_struct_blob(srv_sig_blob, srv_sig_wipe,
    222                                        srv_sig_wipe,
    223                                        (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA);
    224         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    225                 status = ndr_map_error2ntstatus(ndr_err);
    226                 DEBUG(0,("can't parse the SRV signature: %s\n",
    227                         nt_errstr(status)));
    228                 return status;
    229         }
    230 
    231         /* Now zero the decoded structure */
    232         memset(kdc_sig_wipe->signature.data, '\0', kdc_sig_wipe->signature.length);
    233         memset(srv_sig_wipe->signature.data, '\0', srv_sig_wipe->signature.length);
    234 
    235         /* and reencode, back into the same place it came from */
    236         ndr_err = ndr_push_struct_blob(kdc_sig_blob, pac_data_raw,
    237                                        kdc_sig_wipe,
    238                                        (ndr_push_flags_fn_t)ndr_push_PAC_SIGNATURE_DATA);
    239         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    240                 status = ndr_map_error2ntstatus(ndr_err);
    241                 DEBUG(0,("can't repack the KDC signature: %s\n",
    242                         nt_errstr(status)));
    243                 return status;
    244         }
    245         ndr_err = ndr_push_struct_blob(srv_sig_blob, pac_data_raw,
    246                                        srv_sig_wipe,
    247                                        (ndr_push_flags_fn_t)ndr_push_PAC_SIGNATURE_DATA);
    248         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    249                 status = ndr_map_error2ntstatus(ndr_err);
    250                 DEBUG(0,("can't repack the SRV signature: %s\n",
    251                         nt_errstr(status)));
    252                 return status;
    253         }
    254 
    255         /* push out the whole structure, but now with zero'ed signatures */
    256         ndr_err = ndr_push_struct_blob(&modified_pac_blob, pac_data_raw,
    257                                        pac_data_raw,
    258                                        (ndr_push_flags_fn_t)ndr_push_PAC_DATA_RAW);
    259         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    260                 status = ndr_map_error2ntstatus(ndr_err);
    261                 DEBUG(0,("can't repack the RAW PAC: %s\n",
    262                         nt_errstr(status)));
    263                 return status;
    264         }
    265 
    266         /* verify by service_key */
    267         ret = check_pac_checksum(mem_ctx,
    268                                  modified_pac_blob, srv_sig_ptr,
    269                                  context,
    270                                  service_keyblock);
    271         if (ret) {
    272                 DEBUG(1, ("PAC Decode: Failed to verify the service signature: %s\n",
    273                           smb_get_krb5_error_message(context, ret, mem_ctx)));
    274                 if (k5ret) {
    275                         *k5ret = ret;
    276                 }
    277                 return NT_STATUS_ACCESS_DENIED;
    278         }
    279 
    280         if (krbtgt_keyblock) {
    281                 ret = check_pac_checksum(mem_ctx,
    282                                             srv_sig_ptr->signature, kdc_sig_ptr,
    283                                             context, krbtgt_keyblock);
    284                 if (ret) {
    285                         DEBUG(1, ("PAC Decode: Failed to verify the KDC signature: %s\n",
    286                                   smb_get_krb5_error_message(context, ret, mem_ctx)));
    287                         if (k5ret) {
    288                                 *k5ret = ret;
    289                         }
    290                         return NT_STATUS_ACCESS_DENIED;
    291                 }
    292         }
    293 
    294         /* Convert to NT time, so as not to loose accuracy in comparison */
    295         unix_to_nt_time(&tgs_authtime_nttime, tgs_authtime);
    296 
    297         if (tgs_authtime_nttime != logon_name->logon_time) {
    298                 DEBUG(2, ("PAC Decode: Logon time mismatch between ticket and PAC!\n"));
    299                 DEBUG(2, ("PAC Decode: PAC: %s\n", nt_time_string(mem_ctx, logon_name->logon_time)));
    300                 DEBUG(2, ("PAC Decode: Ticket: %s\n", nt_time_string(mem_ctx, tgs_authtime_nttime)));
    301                 return NT_STATUS_ACCESS_DENIED;
    302         }
    303 
    304         ret = krb5_parse_name_flags(context, logon_name->account_name, KRB5_PRINCIPAL_PARSE_NO_REALM,
    305                                     &client_principal_pac);
    306         if (ret) {
    307                 DEBUG(2, ("Could not parse name from incoming PAC: [%s]: %s\n",
    308                           logon_name->account_name,
    309                           smb_get_krb5_error_message(context, ret, mem_ctx)));
    310                 if (k5ret) {
    311                         *k5ret = ret;
    312                 }
    313                 return NT_STATUS_INVALID_PARAMETER;
    314         }
    315 
    316         if (!krb5_principal_compare_any_realm(context, client_principal, client_principal_pac)) {
    317                 DEBUG(2, ("Name in PAC [%s] does not match principal name in ticket\n",
    318                           logon_name->account_name));
    319                 krb5_free_principal(context, client_principal_pac);
    320                 return NT_STATUS_ACCESS_DENIED;
    321         }
    322 
    323         krb5_free_principal(context, client_principal_pac);
    324 
    325 #if 0
    326         if (strcasecmp(logon_info->info3.base.account_name.string,
    327                        "Administrator")== 0) {
    328                 file_save("tmp_pac_data-admin.dat",blob.data,blob.length);
    329         }
    330 #endif
    331 
    332         DEBUG(3,("Found account name from PAC: %s [%s]\n",
    333                  logon_info->info3.base.account_name.string,
    334                  logon_info->info3.base.full_name.string));
    335         *pac_data_out = pac_data;
    336 
    337         return NT_STATUS_OK;
    338 }
    339 
    340 _PUBLIC_  NTSTATUS kerberos_pac_logon_info(TALLOC_CTX *mem_ctx,
    341                                   struct PAC_LOGON_INFO **logon_info,
    342                                   DATA_BLOB blob,
    343                                   krb5_context context,
    344                                   const krb5_keyblock *krbtgt_keyblock,
    345                                   const krb5_keyblock *service_keyblock,
    346                                   krb5_const_principal client_principal,
    347                                   time_t tgs_authtime,
    348                                   krb5_error_code *k5ret)
    349 {
    350         NTSTATUS nt_status;
    351         struct PAC_DATA *pac_data;
    352         int i;
    353         nt_status = kerberos_decode_pac(mem_ctx,
    354                                         &pac_data,
    355                                         blob,
    356                                         context,
    357                                         krbtgt_keyblock,
    358                                         service_keyblock,
    359                                         client_principal,
    360                                         tgs_authtime,
    361                                         k5ret);
    362         if (!NT_STATUS_IS_OK(nt_status)) {
    363                 return nt_status;
    364         }
    365 
    366         *logon_info = NULL;
    367         for (i=0; i < pac_data->num_buffers; i++) {
    368                 if (pac_data->buffers[i].type != PAC_TYPE_LOGON_INFO) {
    369                         continue;
    370                 }
    371                 *logon_info = pac_data->buffers[i].info->logon_info.info;
    372         }
    373         if (!*logon_info) {
    374                 return NT_STATUS_INVALID_PARAMETER;
    375         }
    376         return NT_STATUS_OK;
    377 }
    378 
    379 static krb5_error_code make_pac_checksum(TALLOC_CTX *mem_ctx,
    380                                          DATA_BLOB *pac_data,
    381                                          struct PAC_SIGNATURE_DATA *sig,
    382                                          krb5_context context,
    383                                          const krb5_keyblock *keyblock)
    384 {
    385         krb5_error_code ret;
    386         krb5_crypto crypto;
    387         Checksum cksum;
    388 
    389 
    390         ret = krb5_crypto_init(context,
    391                                keyblock,
    392                                0,
    393                                &crypto);
    394         if (ret) {
    395                 DEBUG(0,("krb5_crypto_init() failed: %s\n",
    396                           smb_get_krb5_error_message(context, ret, mem_ctx)));
    397                 return ret;
    398         }
    399         ret = krb5_create_checksum(context,
    400                                    crypto,
    401                                    KRB5_KU_OTHER_CKSUM,
    402                                    0,
    403                                    pac_data->data,
    404                                    pac_data->length,
    405                                    &cksum);
    406         if (ret) {
    407                 DEBUG(2, ("PAC Verification failed: %s\n",
    408                           smb_get_krb5_error_message(context, ret, mem_ctx)));
    409         }
    410 
    411         krb5_crypto_destroy(context, crypto);
    412 
    413         if (ret) {
    414                 return ret;
    415         }
    416 
    417         sig->type = cksum.cksumtype;
    418         sig->signature = data_blob_talloc(mem_ctx, cksum.checksum.data, cksum.checksum.length);
    419         free_Checksum(&cksum);
    420 
    421         return 0;
    422 }
     33#include "auth/credentials/credentials.h"
     34#include "auth/kerberos/kerberos_util.h"
     35#include "auth/kerberos/pac_utils.h"
    42336
    42437 krb5_error_code kerberos_encode_pac(TALLOC_CTX *mem_ctx,
     
    44457                }
    44558                kdc_checksum = &pac_data->buffers[i].info->kdc_cksum,
    446                 ret = make_pac_checksum(mem_ctx, &zero_blob,
    447                                         kdc_checksum,
    448                                         context, krbtgt_keyblock);
     59                ret = smb_krb5_make_pac_checksum(mem_ctx,
     60                                                 &zero_blob,
     61                                                 context,
     62                                                 krbtgt_keyblock,
     63                                                 &kdc_checksum->type,
     64                                                 &kdc_checksum->signature);
    44965                if (ret) {
    45066                        DEBUG(2, ("making krbtgt PAC checksum failed: %s\n",
     
    46076                }
    46177                srv_checksum = &pac_data->buffers[i].info->srv_cksum;
    462                 ret = make_pac_checksum(mem_ctx, &zero_blob,
    463                                         srv_checksum,
    464                                         context, service_keyblock);
     78                ret = smb_krb5_make_pac_checksum(mem_ctx,
     79                                                 &zero_blob,
     80                                                 context,
     81                                                 service_keyblock,
     82                                                 &srv_checksum->type,
     83                                                 &srv_checksum->signature);
    46584                if (ret) {
    46685                        DEBUG(2, ("making service PAC checksum failed: %s\n",
     
    495114
    496115        /* Then sign the result of the previous push, where the sig was zero'ed out */
    497         ret = make_pac_checksum(mem_ctx, &tmp_blob, srv_checksum,
    498                                 context, service_keyblock);
     116        ret = smb_krb5_make_pac_checksum(mem_ctx,
     117                                         &tmp_blob,
     118                                         context,
     119                                         service_keyblock,
     120                                         &srv_checksum->type,
     121                                         &srv_checksum->signature);
    499122
    500123        /* Then sign Server checksum */
    501         ret = make_pac_checksum(mem_ctx, &srv_checksum->signature, kdc_checksum, context, krbtgt_keyblock);
     124        ret = smb_krb5_make_pac_checksum(mem_ctx,
     125                                         &srv_checksum->signature,
     126                                         context,
     127                                         krbtgt_keyblock,
     128                                         &kdc_checksum->type,
     129                                         &kdc_checksum->signature);
    502130        if (ret) {
    503131                DEBUG(2, ("making krbtgt PAC checksum failed: %s\n",
     
    624252
    625253        ret = krb5_unparse_name_flags(context, client_principal,
    626                                       KRB5_PRINCIPAL_UNPARSE_NO_REALM, &name);
     254                                      KRB5_PRINCIPAL_UNPARSE_NO_REALM |
     255                                      KRB5_PRINCIPAL_UNPARSE_DISPLAY,
     256                                      &name);
    627257        if (ret) {
    628258                return ret;
     
    680310                                      PAC_TYPE_LOGON_INFO,
    681311                                      (ndr_pull_flags_fn_t)ndr_pull_PAC_INFO);
    682         krb5_data_free(&k5pac_logon_info_in);
     312        kerberos_free_data_contents(context, &k5pac_logon_info_in);
    683313        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err) || !info.logon_info.info) {
    684314                nt_status = ndr_map_error2ntstatus(ndr_err);
     
    709339                                               pac_srv_sig,
    710340                                               (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA);
    711                 krb5_data_free(&k5pac_srv_checksum_in);
     341                kerberos_free_data_contents(context, &k5pac_srv_checksum_in);
    712342                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    713343                        nt_status = ndr_map_error2ntstatus(ndr_err);
     
    730360                                               pac_kdc_sig,
    731361                                               (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA);
    732                 krb5_data_free(&k5pac_kdc_checksum_in);
     362                kerberos_free_data_contents(context, &k5pac_kdc_checksum_in);
    733363                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    734364                        nt_status = ndr_map_error2ntstatus(ndr_err);
     
    757387                             &pac);
    758388        if (ret) {
    759                 return map_nt_error_from_unix(ret);
     389                return map_nt_error_from_unix_common(ret);
    760390        }
    761391
     
    764394        krb5_pac_free(context, pac);
    765395        if (ret) {
    766                 return map_nt_error_from_unix(ret);
     396                return map_nt_error_from_unix_common(ret);
    767397        }
    768398        return NT_STATUS_OK;
  • vendor/current/source4/auth/kerberos/kerberos_util.c

    r740 r988  
    2929#include "auth/kerberos/kerberos_credentials.h"
    3030#include "auth/kerberos/kerberos_util.h"
    31 #include <ldb.h>
    32 #include "param/secrets.h"
    3331
    3432struct principal_container {
     
    6462
    6563        if (ret) {
    66                 (*error_string) = smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, parent_ctx);
     64                (*error_string) = smb_get_krb5_error_message(
     65                                                smb_krb5_context->krb5_context,
     66                                                ret, parent_ctx);
    6767                return ret;
    6868        }
     
    7676        /* This song-and-dance effectivly puts the principal
    7777         * into talloc, so we can't loose it. */
    78         mem_ctx->smb_krb5_context = talloc_reference(mem_ctx, smb_krb5_context);
     78        mem_ctx->smb_krb5_context = talloc_reference(mem_ctx,
     79                                                     smb_krb5_context);
    7980        mem_ctx->principal = *princ;
    8081        talloc_set_destructor(mem_ctx, free_principal);
    8182        return 0;
    82 }
    83 
    84 static krb5_error_code principals_from_msg(TALLOC_CTX *parent_ctx,
    85                                            struct ldb_message *msg,
    86                                            struct smb_krb5_context *smb_krb5_context,
    87                                            struct principal_container ***principals_out,
    88                                            const char **error_string)
    89 {
    90         unsigned int i;
    91         krb5_error_code ret;
    92         char *upper_realm;
    93         const char *realm = ldb_msg_find_attr_as_string(msg, "realm", NULL);
    94         const char *samAccountName = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL);
    95         struct ldb_message_element *spn_el = ldb_msg_find_element(msg, "servicePrincipalName");
    96         TALLOC_CTX *tmp_ctx;
    97         struct principal_container **principals;
    98         tmp_ctx = talloc_new(parent_ctx);
    99         if (!tmp_ctx) {
    100                 *error_string = "Cannot allocate tmp_ctx";
    101                 return ENOMEM;
    102         }
    103 
    104         if (!realm) {
    105                 *error_string = "Cannot have a kerberos secret in secrets.ldb without a realm";
    106                 return EINVAL;
    107         }
    108 
    109         upper_realm = strupper_talloc(tmp_ctx, realm);
    110         if (!upper_realm) {
    111                 talloc_free(tmp_ctx);
    112                 *error_string = "Cannot allocate full upper case realm";
    113                 return ENOMEM;
    114         }
    115 
    116         principals = talloc_array(tmp_ctx, struct principal_container *, spn_el ? (spn_el->num_values + 2) : 2);
    117 
    118         spn_el = ldb_msg_find_element(msg, "servicePrincipalName");
    119         for (i=0; spn_el && i < spn_el->num_values; i++) {
    120                 principals[i] = talloc(principals, struct principal_container);
    121                 if (!principals[i]) {
    122                         talloc_free(tmp_ctx);
    123                         *error_string = "Cannot allocate mem_ctx";
    124                         return ENOMEM;
    125                 }
    126 
    127                 principals[i]->smb_krb5_context = talloc_reference(principals[i], smb_krb5_context);
    128                 principals[i]->string_form = talloc_asprintf(principals[i], "%*.*s@%s",
    129                                                              (int)spn_el->values[i].length,
    130                                                              (int)spn_el->values[i].length,
    131                                                              (const char *)spn_el->values[i].data, upper_realm);
    132                 if (!principals[i]->string_form) {
    133                         talloc_free(tmp_ctx);
    134                         *error_string = "Cannot allocate full samAccountName";
    135                         return ENOMEM;
    136                 }
    137 
    138                 ret = krb5_parse_name(smb_krb5_context->krb5_context,
    139                                       principals[i]->string_form, &principals[i]->principal);
    140                
    141                 if (ret) {
    142                         talloc_free(tmp_ctx);
    143                         (*error_string) = smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, parent_ctx);
    144                         return ret;
    145                 }
    146 
    147                 /* This song-and-dance effectivly puts the principal
    148                  * into talloc, so we can't loose it. */
    149                 talloc_set_destructor(principals[i], free_principal);
    150         }
    151 
    152         if (samAccountName) {
    153                 principals[i] = talloc(principals, struct principal_container);
    154                 if (!principals[i]) {
    155                         talloc_free(tmp_ctx);
    156                         *error_string = "Cannot allocate mem_ctx";
    157                         return ENOMEM;
    158                 }
    159 
    160                 principals[i]->smb_krb5_context = talloc_reference(principals[i], smb_krb5_context);
    161                 principals[i]->string_form = talloc_asprintf(parent_ctx, "%s@%s", samAccountName, upper_realm);
    162                 if (!principals[i]->string_form) {
    163                         talloc_free(tmp_ctx);
    164                         *error_string = "Cannot allocate full samAccountName";
    165                         return ENOMEM;
    166                 }
    167                
    168                 ret = krb5_make_principal(smb_krb5_context->krb5_context, &principals[i]->principal, upper_realm, samAccountName,
    169                                           NULL);
    170                 if (ret) {
    171                         talloc_free(tmp_ctx);
    172                         (*error_string) = smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, parent_ctx);
    173                         return ret;
    174                 }
    175                
    176                 /* This song-and-dance effectivly puts the principal
    177                  * into talloc, so we can't loose it. */
    178                 talloc_set_destructor(principals[i], free_principal);
    179                 i++;
    180         }
    181 
    182         principals[i] = NULL;
    183         *principals_out = talloc_steal(parent_ctx, principals);
    184 
    185         talloc_free(tmp_ctx);
    186         return ret;
    187 }
    188 
    189 static krb5_error_code salt_principal_from_msg(TALLOC_CTX *parent_ctx,
    190                                                struct ldb_message *msg,
    191                                                struct smb_krb5_context *smb_krb5_context,
    192                                                krb5_principal *salt_princ,
    193                                                const char **error_string)
    194 {
    195         const char *salt_principal = ldb_msg_find_attr_as_string(msg, "saltPrincipal", NULL);
    196         const char *samAccountName = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL);
    197         const char *realm = ldb_msg_find_attr_as_string(msg, "realm", NULL);
    198         if (salt_principal) {
    199                 return parse_principal(parent_ctx, salt_principal, smb_krb5_context, salt_princ, error_string);
    200         } else if (samAccountName) {
    201                 krb5_error_code ret;
    202                 char *machine_username;
    203                 char *salt_body;
    204                 char *lower_realm;
    205                 char *upper_realm;
    206 
    207                 TALLOC_CTX *tmp_ctx;
    208                 struct principal_container *mem_ctx = talloc(parent_ctx, struct principal_container);
    209                 if (!mem_ctx) {
    210                         *error_string = "Cannot allocate mem_ctx";
    211                         return ENOMEM;
    212                 }
    213 
    214                 tmp_ctx = talloc_new(mem_ctx);
    215                 if (!tmp_ctx) {
    216                         talloc_free(mem_ctx);
    217                         *error_string = "Cannot allocate tmp_ctx";
    218                         return ENOMEM;
    219                 }
    220 
    221                 if (!realm) {
    222                         *error_string = "Cannot have a kerberos secret in secrets.ldb without a realm";
    223                         return EINVAL;
    224                 }
    225                
    226                 machine_username = talloc_strdup(tmp_ctx, samAccountName);
    227                 if (!machine_username) {
    228                         talloc_free(mem_ctx);
    229                         *error_string = "Cannot duplicate samAccountName";
    230                         return ENOMEM;
    231                 }
    232                
    233                 if (machine_username[strlen(machine_username)-1] == '$') {
    234                         machine_username[strlen(machine_username)-1] = '\0';
    235                 }
    236 
    237                 lower_realm = strlower_talloc(tmp_ctx, realm);
    238                 if (!lower_realm) {
    239                         talloc_free(mem_ctx);
    240                         *error_string = "Cannot allocate to lower case realm";
    241                         return ENOMEM;
    242                 }
    243                
    244                 upper_realm = strupper_talloc(tmp_ctx, realm);
    245                 if (!upper_realm) {
    246                         talloc_free(mem_ctx);
    247                         *error_string = "Cannot allocate to upper case realm";
    248                         return ENOMEM;
    249                 }
    250                
    251                 salt_body = talloc_asprintf(tmp_ctx, "%s.%s", machine_username,
    252                                             lower_realm);
    253                 talloc_free(lower_realm);
    254                 talloc_free(machine_username);
    255                 if (!salt_body) {
    256                         talloc_free(mem_ctx);
    257                         *error_string = "Cannot form salt principal body";
    258                         return ENOMEM;
    259                 }
    260                
    261                 ret = krb5_make_principal(smb_krb5_context->krb5_context, salt_princ,
    262                                           upper_realm,
    263                                           "host", salt_body, NULL);
    264                 if (ret == 0) {
    265                         /* This song-and-dance effectivly puts the principal
    266                          * into talloc, so we can't loose it. */
    267                         mem_ctx->smb_krb5_context = talloc_reference(mem_ctx, smb_krb5_context);
    268                         mem_ctx->principal = *salt_princ;
    269                         talloc_set_destructor(mem_ctx, free_principal);
    270                 } else {
    271                         (*error_string) = smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, parent_ctx);
    272                 }
    273                 talloc_free(tmp_ctx);
    274                 return ret;
    275         } else {
    276                 (*error_string) = "Cannot determine salt principal, no saltPrincipal or samAccountName specified";
    277                 return EINVAL;
    278         }
    27983}
    28084
     
    28488 * system by means of a destructor (do *not* free). */
    28589
    286 krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx, 
    287                                             struct cli_credentials *credentials,
    288                                             struct smb_krb5_context *smb_krb5_context,
    289                                             krb5_principal *princ,
    290                                             enum credentials_obtained *obtained,
    291                                             const char **error_string)
     90krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx,
     91                                struct cli_credentials *credentials,
     92                                struct smb_krb5_context *smb_krb5_context,
     93                                krb5_principal *princ,
     94                                enum credentials_obtained *obtained,
     95                                const char **error_string)
    29296{
    29397        krb5_error_code ret;
    29498        const char *princ_string;
    29599        TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);
     100        *obtained = CRED_UNINITIALISED;
     101
    296102        if (!mem_ctx) {
    297103                (*error_string) = error_message(ENOMEM);
    298104                return ENOMEM;
    299105        }
    300         princ_string = cli_credentials_get_principal_and_obtained(credentials, mem_ctx, obtained);
     106        princ_string = cli_credentials_get_principal_and_obtained(credentials,
     107                                                                  mem_ctx,
     108                                                                  obtained);
    301109        if (!princ_string) {
    302                 (*error_string) = error_message(ENOMEM);
    303                 return ENOMEM;
     110                *princ = NULL;
     111                return 0;
    304112        }
    305113
     
    315123 * system by means of a destructor (do *not* free). */
    316124
    317  krb5_error_code impersonate_principal_from_credentials(TALLOC_CTX *parent_ctx,
    318                                                         struct cli_credentials *credentials,
    319                                                         struct smb_krb5_context *smb_krb5_context,
    320                                                         krb5_principal *princ,
    321                                                         const char **error_string)
    322 {
    323         return parse_principal(parent_ctx, cli_credentials_get_impersonate_principal(credentials),
    324                                smb_krb5_context, princ, error_string);
     125static krb5_error_code impersonate_principal_from_credentials(
     126                                TALLOC_CTX *parent_ctx,
     127                                struct cli_credentials *credentials,
     128                                struct smb_krb5_context *smb_krb5_context,
     129                                krb5_principal *princ,
     130                                const char **error_string)
     131{
     132        return parse_principal(parent_ctx,
     133                        cli_credentials_get_impersonate_principal(credentials),
     134                        smb_krb5_context, princ, error_string);
     135}
     136
     137krb5_error_code smb_krb5_create_principals_array(TALLOC_CTX *mem_ctx,
     138                                                 krb5_context context,
     139                                                 const char *account_name,
     140                                                 const char *realm,
     141                                                 uint32_t num_spns,
     142                                                 const char *spns[],
     143                                                 uint32_t *pnum_principals,
     144                                                 krb5_principal **pprincipals,
     145                                                 const char **error_string)
     146{
     147        krb5_error_code code;
     148        TALLOC_CTX *tmp_ctx;
     149        uint32_t num_principals = 0;
     150        krb5_principal *principals;
     151        uint32_t i;
     152
     153        tmp_ctx = talloc_new(mem_ctx);
     154        if (tmp_ctx == NULL) {
     155                *error_string = "Cannot allocate tmp_ctx";
     156                return ENOMEM;
     157        }
     158
     159        if (realm == NULL) {
     160                *error_string = "Cannot create principal without a realm";
     161                code = EINVAL;
     162                goto done;
     163        }
     164
     165        if (account_name == NULL && (num_spns == 0 || spns == NULL)) {
     166                *error_string = "Cannot create principal without an account or SPN";
     167                code = EINVAL;
     168                goto done;
     169        }
     170
     171        if (account_name != NULL && account_name[0] != '\0') {
     172                num_principals++;
     173        }
     174        num_principals += num_spns;
     175
     176        principals = talloc_zero_array(tmp_ctx,
     177                                       krb5_principal,
     178                                       num_principals);
     179        if (principals == NULL) {
     180                *error_string = "Cannot allocate principals";
     181                code = ENOMEM;
     182                goto done;
     183        }
     184
     185        for (i = 0; i < num_spns; i++) {
     186                code = krb5_parse_name(context, spns[i], &(principals[i]));
     187                if (code != 0) {
     188                        *error_string = smb_get_krb5_error_message(context,
     189                                                                   code,
     190                                                                   mem_ctx);
     191                        goto done;
     192                }
     193        }
     194
     195        if (account_name != NULL && account_name[0] != '\0') {
     196                code = smb_krb5_make_principal(context,
     197                                               &(principals[i]),
     198                                               realm,
     199                                               account_name,
     200                                               NULL);
     201                if (code != 0) {
     202                        *error_string = smb_get_krb5_error_message(context,
     203                                                                   code,
     204                                                                   mem_ctx);
     205                        goto done;
     206                }
     207        }
     208
     209        if (pnum_principals != NULL) {
     210                *pnum_principals = num_principals;
     211
     212                if (pprincipals != NULL) {
     213                        *pprincipals = talloc_steal(mem_ctx, principals);
     214                }
     215        }
     216
     217        code = 0;
     218done:
     219        talloc_free(tmp_ctx);
     220        return code;
    325221}
    326222
     
    339235{
    340236        krb5_error_code ret;
    341         const char *password, *target_service;
     237        const char *password;
     238#ifdef SAMBA4_USES_HEIMDAL
     239        const char *self_service;
     240#endif
     241        const char *target_service;
    342242        time_t kdc_time = 0;
    343243        krb5_principal princ;
     
    358258        }
    359259
     260        if (princ == NULL) {
     261                (*error_string) = talloc_asprintf(credentials, "principal, username or realm was not specified in the credentials");
     262                talloc_free(mem_ctx);
     263                return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
     264        }
     265
    360266        ret = impersonate_principal_from_credentials(mem_ctx, credentials, smb_krb5_context, &impersonate_principal, error_string);
    361267        if (ret) {
     
    364270        }
    365271
     272#ifdef SAMBA4_USES_HEIMDAL
     273        self_service = cli_credentials_get_self_service(credentials);
     274#endif
    366275        target_service = cli_credentials_get_target_service(credentials);
    367276
     
    377286        }
    378287
     288#ifdef SAMBA4_USES_HEIMDAL /* Disable for now MIT reads defaults when needed */
    379289        /* get the defaults */
    380290        krb5_get_init_creds_opt_set_default_flags(smb_krb5_context->krb5_context, NULL, NULL, krb_options);
    381 
     291#endif
    382292        /* set if we want a forwardable ticket */
    383293        switch (cli_credentials_get_krb_forwardable(credentials)) {
     
    392302        }
    393303
     304#ifdef SAMBA4_USES_HEIMDAL /* FIXME: MIT does not have this yet */
     305        /*
     306         * In order to work against windows KDCs even if we use
     307         * the netbios domain name as realm, we need to add the following
     308         * flags:
     309         * KRB5_INIT_CREDS_NO_C_CANON_CHECK;
     310         * KRB5_INIT_CREDS_NO_C_NO_EKU_CHECK;
     311         *
     312         * On MIT: Set pkinit_eku_checking to none
     313         */
     314        krb5_get_init_creds_opt_set_win2k(smb_krb5_context->krb5_context,
     315                                          krb_options, true);
     316#else /* MIT */
     317        krb5_get_init_creds_opt_set_canonicalize(krb_options, true);
     318#endif
     319
    394320        tries = 2;
    395321        while (tries--) {
     322#ifdef SAMBA4_USES_HEIMDAL
    396323                struct tevent_context *previous_ev;
    397324                /* Do this every time, in case we have weird recursive issues here */
     
    401328                        return ret;
    402329                }
     330#endif
    403331                if (password) {
    404                         ret = kerberos_kinit_password_cc(smb_krb5_context->krb5_context, ccache,
    405                                                          princ, password,
    406                                                          impersonate_principal, target_service,
    407                                                          krb_options,
    408                                                          NULL, &kdc_time);
     332                        if (impersonate_principal) {
     333#ifdef SAMBA4_USES_HEIMDAL
     334                                ret = kerberos_kinit_s4u2_cc(
     335                                                smb_krb5_context->krb5_context,
     336                                                ccache, princ, password,
     337                                                impersonate_principal,
     338                                                self_service, target_service,
     339                                                krb_options, NULL, &kdc_time);
     340#else
     341                                talloc_free(mem_ctx);
     342                                (*error_string) = "INTERNAL error: s4u2 ops "
     343                                        "are not supported with MIT build yet";
     344                                return EINVAL;
     345#endif
     346                        } else {
     347                                ret = kerberos_kinit_password_cc(
     348                                                smb_krb5_context->krb5_context,
     349                                                ccache, princ, password,
     350                                                target_service,
     351                                                krb_options, NULL, &kdc_time);
     352                        }
    409353                } else if (impersonate_principal) {
    410354                        talloc_free(mem_ctx);
     
    421365                                (*error_string) = "kinit_to_ccache: No password available for kinit\n";
    422366                                krb5_get_init_creds_opt_free(smb_krb5_context->krb5_context, krb_options);
     367#ifdef SAMBA4_USES_HEIMDAL
    423368                                smb_krb5_context_remove_event_ctx(smb_krb5_context, previous_ev, event_ctx);
     369#endif
    424370                                return EINVAL;
    425371                        }
    426                         ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
     372                        ret = smb_krb5_keyblock_init_contents(smb_krb5_context->krb5_context,
    427373                                                 ENCTYPE_ARCFOUR_HMAC,
    428374                                                 mach_pwd->hash, sizeof(mach_pwd->hash),
     
    438384                }
    439385
     386#ifdef SAMBA4_USES_HEIMDAL
    440387                smb_krb5_context_remove_event_ctx(smb_krb5_context, previous_ev, event_ctx);
     388#endif
    441389
    442390                if (ret == KRB5KRB_AP_ERR_SKEW || ret == KRB5_KDCREP_SKEW) {
     
    485433                talloc_free(mem_ctx);
    486434                return ret;
    487         }
     435        }
     436
     437        DEBUG(10,("kinit for %s succeeded\n",
     438                cli_credentials_get_principal(credentials, mem_ctx)));
     439
     440
    488441        talloc_free(mem_ctx);
    489442        return 0;
    490443}
    491444
    492 static krb5_error_code free_keytab(struct keytab_container *ktc)
     445static krb5_error_code free_keytab_container(struct keytab_container *ktc)
    493446{
    494447        return krb5_kt_close(ktc->smb_krb5_context->krb5_context, ktc->keytab);
    495448}
    496449
    497 krb5_error_code smb_krb5_open_keytab(TALLOC_CTX *mem_ctx,
    498                          struct smb_krb5_context *smb_krb5_context,
    499                          const char *keytab_name, struct keytab_container **ktc)
     450krb5_error_code smb_krb5_get_keytab_container(TALLOC_CTX *mem_ctx,
     451                                struct smb_krb5_context *smb_krb5_context,
     452                                krb5_keytab opt_keytab,
     453                                const char *keytab_name,
     454                                struct keytab_container **ktc)
    500455{
    501456        krb5_keytab keytab;
    502457        krb5_error_code ret;
    503         ret = krb5_kt_resolve(smb_krb5_context->krb5_context, keytab_name, &keytab);
    504         if (ret) {
    505                 DEBUG(1,("failed to open krb5 keytab: %s\n",
    506                          smb_get_krb5_error_message(smb_krb5_context->krb5_context,
    507                                                     ret, mem_ctx)));
    508                 return ret;
     458
     459        if (opt_keytab) {
     460                keytab = opt_keytab;
     461        } else {
     462                ret = krb5_kt_resolve(smb_krb5_context->krb5_context,
     463                                                keytab_name, &keytab);
     464                if (ret) {
     465                        DEBUG(1,("failed to open krb5 keytab: %s\n",
     466                                 smb_get_krb5_error_message(
     467                                        smb_krb5_context->krb5_context,
     468                                        ret, mem_ctx)));
     469                        return ret;
     470                }
    509471        }
    510472
     
    516478        (*ktc)->smb_krb5_context = talloc_reference(*ktc, smb_krb5_context);
    517479        (*ktc)->keytab = keytab;
    518         talloc_set_destructor(*ktc, free_keytab);
     480        (*ktc)->password_based = false;
     481        talloc_set_destructor(*ktc, free_keytab_container);
    519482
    520483        return 0;
    521484}
    522485
    523 static krb5_error_code keytab_add_keys(TALLOC_CTX *parent_ctx,
    524                                        struct principal_container **principals,
    525                                        krb5_principal salt_princ,
    526                                        int kvno,
    527                                        const char *password_s,
    528                                        struct smb_krb5_context *smb_krb5_context,
    529                                        krb5_enctype *enctypes,
    530                                        krb5_keytab keytab,
    531                                        const char **error_string)
    532 {
    533         unsigned int i, p;
    534         krb5_error_code ret;
    535         krb5_data password;
    536 
    537         password.data = discard_const_p(char *, password_s);
    538         password.length = strlen(password_s);
    539 
    540         for (i=0; enctypes[i]; i++) {
    541                 krb5_keytab_entry entry;
    542 
    543                 ZERO_STRUCT(entry);
    544 
    545                 ret = create_kerberos_key_from_string(smb_krb5_context->krb5_context,
    546                                                       salt_princ, &password, &entry.keyblock, enctypes[i]);
    547                 if (ret != 0) {
    548                         return ret;
    549                 }
    550 
    551                 entry.vno = kvno;
    552 
    553                 for (p=0; principals[p]; p++) {
    554                         entry.principal = principals[p]->principal;
    555                         ret = krb5_kt_add_entry(smb_krb5_context->krb5_context, keytab, &entry);
    556                         if (ret != 0) {
    557                                 char *k5_error_string = smb_get_krb5_error_message(smb_krb5_context->krb5_context,
    558                                                                                    ret, NULL);
    559                                 *error_string = talloc_asprintf(parent_ctx, "Failed to add enctype %d entry for %s(kvno %d) to keytab: %s\n",
    560                                                                 (int)enctypes[i],
    561                                                                 principals[p]->string_form,
    562                                                                 kvno,
    563                                                                 k5_error_string);
    564                                 talloc_free(k5_error_string);
    565                                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &entry.keyblock);
    566                                 return ret;
    567                         }
    568 
    569                         DEBUG(5, ("Added %s(kvno %d) to keytab (enctype %d)\n",
    570                                   principals[p]->string_form, kvno,
    571                                   (int)enctypes[i]));
    572                 }
    573                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &entry.keyblock);
    574         }
    575         return 0;
    576 }
    577 
    578 static krb5_error_code create_keytab(TALLOC_CTX *parent_ctx,
    579                                      struct ldb_message *msg,
    580                                      struct principal_container **principals,
    581                                      struct smb_krb5_context *smb_krb5_context,
    582                                      krb5_keytab keytab,
    583                                      bool add_old,
    584                                      const char **error_string)
    585 {
    586         krb5_error_code ret;
    587         const char *password_s;
    588         const char *old_secret;
    589         int kvno;
    590         uint32_t enctype_bitmap;
    591         krb5_principal salt_princ;
    592         krb5_enctype *enctypes;
    593         TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);
    594         if (!mem_ctx) {
    595                 *error_string = "unable to allocate tmp_ctx for create_keytab";
    596                 return ENOMEM;
    597         }
    598 
    599         /* The salt used to generate these entries may be different however, fetch that */
    600         ret = salt_principal_from_msg(mem_ctx, msg,
    601                                       smb_krb5_context,
    602                                       &salt_princ, error_string);
    603         if (ret) {
    604                 talloc_free(mem_ctx);
    605                 return ret;
    606         }
    607 
    608         kvno = ldb_msg_find_attr_as_int(msg, "msDS-KeyVersionNumber", 0);
    609 
    610         /* Finally, do the dance to get the password to put in the entry */
    611         password_s =  ldb_msg_find_attr_as_string(msg, "secret", NULL);
    612 
    613         if (!password_s) {
    614                 /* There is no password here, so nothing to do */
    615                 talloc_free(mem_ctx);
    616                 return 0;
    617         }
    618 
    619         if (add_old && kvno != 0) {
    620                 old_secret = ldb_msg_find_attr_as_string(msg, "priorSecret", NULL);
    621         } else {
    622                 old_secret = NULL;
    623         }
    624 
    625         enctype_bitmap = (uint32_t)ldb_msg_find_attr_as_int(msg, "msDS-SupportedEncryptionTypes", ENC_ALL_TYPES);
    626        
    627         ret = kerberos_enctype_bitmap_to_enctypes(mem_ctx, enctype_bitmap, &enctypes);
    628         if (ret) {
    629                 *error_string = talloc_asprintf(parent_ctx, "create_keytab: generating list of encryption types failed (%s)\n",
    630                                                 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
    631                                                                            ret, mem_ctx));
    632                 talloc_free(mem_ctx);
    633                 return ret;
    634         }
    635 
    636         ret = keytab_add_keys(mem_ctx, principals,
    637                               salt_princ,
    638                               kvno, password_s, smb_krb5_context,
    639                               enctypes, keytab, error_string);
    640         if (ret) {
    641                 talloc_free(mem_ctx);
    642                 return ret;
    643         }
    644        
    645         if (old_secret) {
    646                 ret = keytab_add_keys(mem_ctx, principals,
    647                                       salt_princ,
    648                                       kvno - 1, old_secret, smb_krb5_context,
    649                                       enctypes, keytab, error_string);
    650                 if (ret) {
    651                         talloc_free(mem_ctx);
    652                         return ret;
    653                 }
    654         }
    655 
    656         talloc_free(mem_ctx);
    657         return ret;
    658 }
    659 
    660486/*
    661  * Walk the keytab, looking for entries of this principal name, with KVNO other than current kvno -1.
     487 * Walk the keytab, looking for entries of this principal name,
     488 * with KVNO other than current kvno -1.
    662489 *
    663  * These entries are now stale, we only keep the current, and previous entries around.
     490 * These entries are now stale,
     491 * we only keep the current and previous entries around.
    664492 *
    665493 * Inspired by the code in Samba3 for 'use kerberos keytab'.
    666  *
    667494 */
    668 
    669 static krb5_error_code remove_old_entries(TALLOC_CTX *parent_ctx,
    670                                           struct ldb_message *msg,
    671                                           struct principal_container **principals,
    672                                           bool delete_all_kvno,
    673                                           struct smb_krb5_context *smb_krb5_context,
    674                                           krb5_keytab keytab, bool *found_previous,
    675                                           const char **error_string)
    676 {
    677         krb5_error_code ret, ret2;
     495krb5_error_code smb_krb5_remove_obsolete_keytab_entries(TALLOC_CTX *mem_ctx,
     496                                                        krb5_context context,
     497                                                        krb5_keytab keytab,
     498                                                        uint32_t num_principals,
     499                                                        krb5_principal *principals,
     500                                                        krb5_kvno kvno,
     501                                                        bool *found_previous,
     502                                                        const char **error_string)
     503{
     504        TALLOC_CTX *tmp_ctx;
     505        krb5_error_code code;
    678506        krb5_kt_cursor cursor;
    679         int kvno;
    680         TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);
    681 
    682         if (!mem_ctx) {
     507
     508        tmp_ctx = talloc_new(mem_ctx);
     509        if (tmp_ctx == NULL) {
     510                *error_string = "Cannot allocate tmp_ctx";
    683511                return ENOMEM;
    684512        }
    685513
    686         *found_previous = false;
    687 
    688         kvno = ldb_msg_find_attr_as_int(msg, "msDS-KeyVersionNumber", 0);
    689 
    690         /* for each entry in the keytab */
    691         ret = krb5_kt_start_seq_get(smb_krb5_context->krb5_context, keytab, &cursor);
    692         switch (ret) {
     514        *found_previous = true;
     515
     516        code = krb5_kt_start_seq_get(context, keytab, &cursor);
     517        switch (code) {
    693518        case 0:
    694519                break;
     520#ifdef HEIM_ERR_OPNOTSUPP
    695521        case HEIM_ERR_OPNOTSUPP:
     522#endif
    696523        case ENOENT:
    697524        case KRB5_KT_END:
    698525                /* no point enumerating if there isn't anything here */
    699                 talloc_free(mem_ctx);
    700                 return 0;
     526                code = 0;
     527                goto done;
    701528        default:
    702                 *error_string = talloc_asprintf(parent_ctx, "failed to open keytab for read of old entries: %s\n",
    703                                                 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
    704                                                                            ret, mem_ctx));
    705                 talloc_free(mem_ctx);
    706                 return ret;
    707         }
    708 
    709         while (!ret) {
    710                 unsigned int i;
     529                *error_string = talloc_asprintf(mem_ctx,
     530                                                "failed to open keytab for read of old entries: %s\n",
     531                                                smb_get_krb5_error_message(context, code, mem_ctx));
     532                goto done;
     533        }
     534
     535        do {
     536                krb5_kvno old_kvno = kvno - 1;
     537                krb5_keytab_entry entry;
    711538                bool matched = false;
    712                 krb5_keytab_entry entry;
    713                 ret = krb5_kt_next_entry(smb_krb5_context->krb5_context, keytab, &entry, &cursor);
    714                 if (ret) {
     539                uint32_t i;
     540
     541                code = krb5_kt_next_entry(context, keytab, &entry, &cursor);
     542                if (code) {
    715543                        break;
    716544                }
    717                 for (i = 0; principals[i]; i++) {
    718                         /* if it matches our principal */
    719                         if (krb5_kt_compare(smb_krb5_context->krb5_context, &entry, principals[i]->principal, 0, 0)) {
     545
     546                for (i = 0; i < num_principals; i++) {
     547                        krb5_boolean ok;
     548
     549                        ok = smb_krb5_kt_compare(context,
     550                                                &entry,
     551                                                principals[i],
     552                                                0,
     553                                                0);
     554                        if (ok) {
    720555                                matched = true;
    721556                                break;
     
    724559
    725560                if (!matched) {
    726                         /* Free the entry, it wasn't the one we were looking for anyway */
    727                         krb5_kt_free_entry(smb_krb5_context->krb5_context, &entry);
     561                        /*
     562                         * Free the entry, it wasn't the one we were looking
     563                         * for anyway
     564                         */
     565                        krb5_kt_free_entry(context, &entry);
     566                        /* Make sure we do not double free */
     567                        ZERO_STRUCT(entry);
    728568                        continue;
    729569                }
    730570
    731                 /* delete it, if it is not kvno -1 */
    732                 if (entry.vno != (kvno - 1 )) {
     571                /*
     572                 * Delete it, if it is not kvno - 1.
     573                 *
     574                 * Some keytab files store the kvno only in 8bits. Limit the
     575                 * compare to 8bits, so that we don't miss old keys and delete
     576                 * them.
     577                 */
     578                if ((entry.vno & 0xff) != (old_kvno & 0xff)) {
     579                        krb5_error_code rc;
     580
    733581                        /* Release the enumeration.  We are going to
    734582                         * have to start this from the top again,
    735583                         * because deletes during enumeration may not
    736                          * always be consistant.
     584                         * always be consistent.
    737585                         *
    738586                         * Also, the enumeration locks a FILE: keytab
    739587                         */
    740                
    741                         krb5_kt_end_seq_get(smb_krb5_context->krb5_context, keytab, &cursor);
    742 
    743                         ret = krb5_kt_remove_entry(smb_krb5_context->krb5_context, keytab, &entry);
    744                         krb5_kt_free_entry(smb_krb5_context->krb5_context, &entry);
     588                        krb5_kt_end_seq_get(context, keytab, &cursor);
     589
     590                        code = krb5_kt_remove_entry(context, keytab, &entry);
     591                        krb5_kt_free_entry(context, &entry);
     592
     593                        /* Make sure we do not double free */
     594                        ZERO_STRUCT(entry);
    745595
    746596                        /* Deleted: Restart from the top */
    747                         ret2 = krb5_kt_start_seq_get(smb_krb5_context->krb5_context, keytab, &cursor);
    748                         if (ret2) {
    749                                 krb5_kt_free_entry(smb_krb5_context->krb5_context, &entry);
    750                                 DEBUG(1,("failed to restart enumeration of keytab: %s\n",
    751                                          smb_get_krb5_error_message(smb_krb5_context->krb5_context,
    752                                                                     ret, mem_ctx)));
    753                                
    754                                 talloc_free(mem_ctx);
    755                                 return ret2;
     597                        rc = krb5_kt_start_seq_get(context, keytab, &cursor);
     598                        if (rc != 0) {
     599                                krb5_kt_free_entry(context, &entry);
     600
     601                                /* Make sure we do not double free */
     602                                ZERO_STRUCT(entry);
     603
     604                                DEBUG(1, ("failed to restart enumeration of keytab: %s\n",
     605                                          smb_get_krb5_error_message(context,
     606                                                                     code,
     607                                                                     tmp_ctx)));
     608
     609                                talloc_free(tmp_ctx);
     610                                return rc;
    756611                        }
    757612
    758                         if (ret) {
     613                        if (code != 0) {
    759614                                break;
    760615                        }
    761                        
     616
    762617                } else {
    763618                        *found_previous = true;
    764619                }
    765                
     620
    766621                /* Free the entry, we don't need it any more */
    767                 krb5_kt_free_entry(smb_krb5_context->krb5_context, &entry);
    768                
    769                
    770         }
    771         krb5_kt_end_seq_get(smb_krb5_context->krb5_context, keytab, &cursor);
    772 
    773         switch (ret) {
     622                krb5_kt_free_entry(context, &entry);
     623                /* Make sure we do not double free */
     624                ZERO_STRUCT(entry);
     625        } while (code != 0);
     626
     627        krb5_kt_end_seq_get(context, keytab, &cursor);
     628
     629        switch (code) {
    774630        case 0:
    775631                break;
    776632        case ENOENT:
    777633        case KRB5_KT_END:
    778                 ret = 0;
     634                code = 0;
    779635                break;
    780636        default:
    781                 *error_string = talloc_asprintf(parent_ctx, "failed in deleting old entries for principal: %s\n",
    782                                                 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
    783                                                                            ret, mem_ctx));
    784         }
    785         talloc_free(mem_ctx);
    786         return ret;
    787 }
    788 
    789 krb5_error_code smb_krb5_update_keytab(TALLOC_CTX *parent_ctx,
    790                                        struct smb_krb5_context *smb_krb5_context,
    791                                        struct ldb_context *ldb,
    792                                        struct ldb_message *msg,
    793                                        bool delete_all_kvno,
    794                                        const char **error_string)
    795 {
    796         krb5_error_code ret;
    797         bool found_previous;
    798         TALLOC_CTX *mem_ctx = talloc_new(NULL);
    799         struct keytab_container *keytab_container;
    800         struct principal_container **principals;
    801         const char *keytab_name;
    802 
    803         if (!mem_ctx) {
    804                 return ENOMEM;
    805         }
    806 
    807         keytab_name = keytab_name_from_msg(mem_ctx, ldb, msg);
    808         if (!keytab_name) {
    809                 return ENOENT;
    810         }
    811 
    812         ret = smb_krb5_open_keytab(mem_ctx, smb_krb5_context, keytab_name, &keytab_container);
    813 
    814         if (ret != 0) {
    815                 talloc_free(mem_ctx);
    816                 return ret;
    817         }
    818 
    819         DEBUG(5, ("Opened keytab %s\n", keytab_name));
    820 
    821         /* Get the principal we will store the new keytab entries under */
    822         ret = principals_from_msg(mem_ctx, msg, smb_krb5_context, &principals, error_string);
    823 
    824         if (ret != 0) {
    825                 *error_string = talloc_asprintf(parent_ctx, "Failed to load principals from ldb message: %s\n", *error_string);
    826                 talloc_free(mem_ctx);
    827                 return ret;
    828         }
    829 
    830         ret = remove_old_entries(mem_ctx, msg, principals, delete_all_kvno,
    831                                  smb_krb5_context, keytab_container->keytab, &found_previous, error_string);
    832         if (ret != 0) {
    833                 *error_string = talloc_asprintf(parent_ctx, "Failed to remove old principals from keytab: %s\n", *error_string);
    834                 talloc_free(mem_ctx);
    835                 return ret;
    836         }
    837        
    838         if (!delete_all_kvno) {
    839                 /* Create a new keytab.  If during the cleanout we found
    840                  * entires for kvno -1, then don't try and duplicate them.
    841                  * Otherwise, add kvno, and kvno -1 */
    842                
    843                 ret = create_keytab(mem_ctx, msg, principals,
    844                                     smb_krb5_context,
    845                                     keytab_container->keytab,
    846                                     found_previous ? false : true, error_string);
    847         }
    848         talloc_free(mem_ctx);
    849         return ret;
    850 }
    851 
    852 krb5_error_code smb_krb5_create_memory_keytab(TALLOC_CTX *parent_ctx,
    853                                            struct cli_credentials *machine_account,
    854                                            struct smb_krb5_context *smb_krb5_context,
    855                                            struct keytab_container **keytab_container)
    856 {
    857         krb5_error_code ret;
    858         TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);
    859         const char *rand_string;
    860         const char *keytab_name;
    861         struct ldb_message *msg;
    862         const char *error_string;
    863         if (!mem_ctx) {
    864                 return ENOMEM;
    865         }
    866        
    867         *keytab_container = talloc(mem_ctx, struct keytab_container);
    868 
    869         rand_string = generate_random_str(mem_ctx, 16);
    870         if (!rand_string) {
    871                 talloc_free(mem_ctx);
    872                 return ENOMEM;
    873         }
    874 
    875         keytab_name = talloc_asprintf(mem_ctx, "MEMORY:%s",
    876                                       rand_string);
    877         if (!keytab_name) {
    878                 talloc_free(mem_ctx);
    879                 return ENOMEM;
    880         }
    881 
    882         ret = smb_krb5_open_keytab(mem_ctx, smb_krb5_context, keytab_name, keytab_container);
    883         if (ret) {
    884                 return ret;
    885         }
    886 
    887         msg = ldb_msg_new(mem_ctx);
    888         if (!msg) {
    889                 talloc_free(mem_ctx);
    890                 return ENOMEM;
    891         }
    892         ldb_msg_add_string(msg, "krb5Keytab", keytab_name);
    893         ldb_msg_add_string(msg, "secret", cli_credentials_get_password(machine_account));
    894         ldb_msg_add_string(msg, "samAccountName", cli_credentials_get_username(machine_account));
    895         ldb_msg_add_string(msg, "realm", cli_credentials_get_realm(machine_account));
    896         ldb_msg_add_fmt(msg, "msDS-KeyVersionNumber", "%d", (int)cli_credentials_get_kvno(machine_account));
    897 
    898         ret = smb_krb5_update_keytab(mem_ctx, smb_krb5_context, NULL, msg, false, &error_string);
    899         if (ret == 0) {
    900                 talloc_steal(parent_ctx, *keytab_container);
    901         } else {
    902                 DEBUG(0, ("Failed to create in-memory keytab: %s\n", error_string));
    903                 *keytab_container = NULL;
    904         }
    905         talloc_free(mem_ctx);
    906         return ret;
    907 }
    908 /* Translate between the IETF encryption type values and the Microsoft msDS-SupportedEncryptionTypes values */
    909 uint32_t kerberos_enctype_to_bitmap(krb5_enctype enc_type_enum)
    910 {
    911         switch (enc_type_enum) {
    912         case ENCTYPE_DES_CBC_CRC:
    913                 return ENC_CRC32;
    914         case ENCTYPE_DES_CBC_MD5:
    915                 return ENC_RSA_MD5;
    916         case ENCTYPE_ARCFOUR_HMAC_MD5:
    917                 return ENC_RC4_HMAC_MD5;
    918         case ENCTYPE_AES128_CTS_HMAC_SHA1_96:
    919                 return ENC_HMAC_SHA1_96_AES128;
    920         case ENCTYPE_AES256_CTS_HMAC_SHA1_96:
    921                 return ENC_HMAC_SHA1_96_AES256;
    922         default:
    923                 return 0;
    924         }
    925 }
    926 
    927 /* Translate between the Microsoft msDS-SupportedEncryptionTypes values and the IETF encryption type values */
    928 krb5_enctype kerberos_enctype_bitmap_to_enctype(uint32_t enctype_bitmap)
    929 {
    930         switch (enctype_bitmap) {
    931         case ENC_CRC32:
    932                 return ENCTYPE_DES_CBC_CRC;
    933         case ENC_RSA_MD5:
    934                 return ENCTYPE_DES_CBC_MD5;
    935         case ENC_RC4_HMAC_MD5:
    936                 return ENCTYPE_ARCFOUR_HMAC_MD5;
    937         case ENC_HMAC_SHA1_96_AES128:
    938                 return ENCTYPE_AES128_CTS_HMAC_SHA1_96;
    939         case ENC_HMAC_SHA1_96_AES256:
    940                 return ENCTYPE_AES256_CTS_HMAC_SHA1_96;
    941         default:
    942                 return 0;
    943         }
    944 }
    945 
    946 /* Return an array of krb5_enctype values */
    947 krb5_error_code kerberos_enctype_bitmap_to_enctypes(TALLOC_CTX *mem_ctx, uint32_t enctype_bitmap, krb5_enctype **enctypes)
    948 {
    949         unsigned int i, j = 0;
    950         *enctypes = talloc_zero_array(mem_ctx, krb5_enctype, (8*sizeof(enctype_bitmap))+1);
    951         if (!*enctypes) {
    952                 return ENOMEM;
    953         }
    954         for (i=0; i<(8*sizeof(enctype_bitmap)); i++) {
    955                 uint32_t bit_value = (1 << i) & enctype_bitmap;
    956                 if (bit_value & enctype_bitmap) {
    957                         (*enctypes)[j] = kerberos_enctype_bitmap_to_enctype(bit_value);
    958                         if (!(*enctypes)[j]) {
    959                                 continue;
    960                         }
    961                         j++;
    962                 }
    963         }
    964         (*enctypes)[j] = 0;
    965         return 0;
    966 }
     637                *error_string = talloc_asprintf(mem_ctx,
     638                                                "failed in deleting old entries for principal: %s\n",
     639                                                smb_get_krb5_error_message(context,
     640                                                                           code,
     641                                                                           mem_ctx));
     642        }
     643
     644        code = 0;
     645done:
     646        talloc_free(tmp_ctx);
     647        return code;
     648}
  • vendor/current/source4/auth/kerberos/krb5_init_context.c

    r740 r988  
    2323#include "includes.h"
    2424#include "system/kerberos.h"
     25#include "system/gssapi.h"
    2526#include <tevent.h>
    2627#include "auth/kerberos/kerberos.h"
     
    3132#include "libcli/resolve/resolve.h"
    3233#include "../lib/tsocket/tsocket.h"
    33 
     34#include "krb5_init_context.h"
    3435/*
    3536  context structure for operations on cldap packets
     
    4748
    4849        size_t partial_read;
    49 
     50#ifdef SAMBA4_USES_HEIMDAL
    5051        krb5_krbhst_info *hi;
     52#endif
    5153};
    5254
    5355static krb5_error_code smb_krb5_context_destroy(struct smb_krb5_context *ctx)
    5456{
    55         /* Otherwise krb5_free_context will try and close what we have already free()ed */
    56         krb5_set_warn_dest(ctx->krb5_context, NULL);
    57         krb5_closelog(ctx->krb5_context, ctx->logf);
     57#ifdef SAMBA4_USES_HEIMDAL
     58        if (ctx->pvt_log_data) {
     59                /* Otherwise krb5_free_context will try and close what we
     60                 * have already free()ed */
     61                krb5_set_warn_dest(ctx->krb5_context, NULL);
     62                krb5_closelog(ctx->krb5_context,
     63                                (krb5_log_facility *)ctx->pvt_log_data);
     64        }
     65#endif
    5866        krb5_free_context(ctx->krb5_context);
    5967        return 0;
    6068}
    6169
     70#ifdef SAMBA4_USES_HEIMDAL
    6271/* We never close down the DEBUG system, and no need to unreference the use */
    6372static void smb_krb5_debug_close(void *private_data) {
    6473        return;
    6574}
    66 
     75#endif
     76
     77#ifdef SAMBA4_USES_HEIMDAL
    6778static void smb_krb5_debug_wrapper(const char *timestr, const char *msg, void *private_data)
    6879{
    6980        DEBUG(3, ("Kerberos: %s\n", msg));
    7081}
    71 
     82#endif
     83
     84#ifdef SAMBA4_USES_HEIMDAL
    7285/*
    7386  handle recv events on a smb_krb5 socket
     
    105118        }
    106119
    107         DEBUG(2,("Received smb_krb5 packet of length %d\n",
     120        DEBUG(4,("Received smb_krb5 packet of length %d\n",
    108121                 (int)blob.length));
    109122
     
    198211}
    199212
    200 
    201 krb5_error_code smb_krb5_send_and_recv_func(krb5_context context,
    202                                             void *data,
    203                                             krb5_krbhst_info *hi,
    204                                             time_t timeout,
    205                                             const krb5_data *send_buf,
    206                                             krb5_data *recv_buf)
     213static krb5_error_code smb_krb5_send_and_recv_func_int(krb5_context context,
     214                                                       struct tevent_context *ev,
     215                                                       krb5_krbhst_info *hi,
     216                                                       struct addrinfo *ai,
     217                                                       krb5_send_to_kdc_func func,
     218                                                       void *data,
     219                                                       time_t timeout,
     220                                                       const krb5_data *send_buf,
     221                                                       krb5_data *recv_buf)
    207222{
    208223        krb5_error_code ret;
    209224        NTSTATUS status;
    210225        const char *name;
    211         struct addrinfo *ai, *a;
     226        struct addrinfo *a;
    212227        struct smb_krb5_socket *smb_krb5;
    213228
    214229        DATA_BLOB send_blob;
    215230
    216         struct tevent_context *ev;
    217         TALLOC_CTX *tmp_ctx = talloc_new(NULL);
    218         if (!tmp_ctx) {
     231        TALLOC_CTX *frame = talloc_stackframe();
     232        if (frame == NULL) {
    219233                return ENOMEM;
    220234        }
    221235
    222         if (!data) {
    223                 /* If no event context was available, then create one for this loop */
    224                 ev = tevent_context_init(tmp_ctx);
    225                 if (!ev) {
    226                         talloc_free(tmp_ctx);
    227                         return ENOMEM;
    228                 }
    229         } else {
    230                 ev = talloc_get_type_abort(data, struct tevent_context);
    231         }
    232 
    233236        send_blob = data_blob_const(send_buf->data, send_buf->length);
    234 
    235         ret = krb5_krbhst_get_addrinfo(context, hi, &ai);
    236         if (ret) {
    237                 talloc_free(tmp_ctx);
    238                 return ret;
    239         }
    240237
    241238        for (a = ai; a; a = a->ai_next) {
    242239                struct socket_address *remote_addr;
    243                 smb_krb5 = talloc(tmp_ctx, struct smb_krb5_socket);
     240                smb_krb5 = talloc(frame, struct smb_krb5_socket);
    244241                if (!smb_krb5) {
    245                         talloc_free(tmp_ctx);
     242                        TALLOC_FREE(frame);
    246243                        return ENOMEM;
    247244                }
     
    258255#endif
    259256                default:
    260                         talloc_free(tmp_ctx);
     257                        TALLOC_FREE(frame);
    261258                        return EINVAL;
    262259                }
     
    271268                        break;
    272269                case KRB5_KRBHST_HTTP:
    273                         talloc_free(tmp_ctx);
     270                        TALLOC_FREE(frame);
    274271                        return EINVAL;
    275272                }
     
    339336                        break;
    340337                case KRB5_KRBHST_HTTP:
    341                         talloc_free(tmp_ctx);
     338                        TALLOC_FREE(frame);
    342339                        return EINVAL;
    343340                }
    344341                while ((NT_STATUS_IS_OK(smb_krb5->status)) && !smb_krb5->reply.length) {
    345342                        if (tevent_loop_once(ev) != 0) {
    346                                 talloc_free(tmp_ctx);
     343                                TALLOC_FREE(frame);
    347344                                return EINVAL;
    348345                        }
    349346
    350                         /* After each and every event loop, reset the
    351                          * send_to_kdc pointers to what they were when
    352                          * we entered this loop.  That way, if a
    353                          * nested event has invalidated them, we put
    354                          * it back before we return to the heimdal
    355                          * code */
    356                         ret = krb5_set_send_to_kdc_func(context,
    357                                                         smb_krb5_send_and_recv_func,
    358                                                         data);
    359                         if (ret != 0) {
    360                                 talloc_free(tmp_ctx);
    361                                 return ret;
     347                        if (func) {
     348                                /* After each and every event loop, reset the
     349                                 * send_to_kdc pointers to what they were when
     350                                 * we entered this loop.  That way, if a
     351                                 * nested event has invalidated them, we put
     352                                 * it back before we return to the heimdal
     353                                 * code */
     354                                ret = krb5_set_send_to_kdc_func(context,
     355                                                                func,
     356                                                                data);
     357                                if (ret != 0) {
     358                                        TALLOC_FREE(frame);
     359                                        return ret;
     360                                }
    362361                        }
    363362                }
     
    383382                ret = krb5_data_copy(recv_buf, smb_krb5->reply.data, smb_krb5->reply.length);
    384383                if (ret) {
    385                         talloc_free(tmp_ctx);
     384                        TALLOC_FREE(frame);
    386385                        return ret;
    387386                }
     
    390389                break;
    391390        }
    392         talloc_free(tmp_ctx);
     391        TALLOC_FREE(frame);
    393392        if (a) {
    394393                return 0;
     
    396395        return KRB5_KDC_UNREACH;
    397396}
     397
     398krb5_error_code smb_krb5_send_and_recv_func(krb5_context context,
     399                                            void *data,
     400                                            krb5_krbhst_info *hi,
     401                                            time_t timeout,
     402                                            const krb5_data *send_buf,
     403                                            krb5_data *recv_buf)
     404{
     405        krb5_error_code ret;
     406        struct addrinfo *ai;
     407
     408        struct tevent_context *ev;
     409        TALLOC_CTX *frame = talloc_stackframe();
     410        if (frame == NULL) {
     411                return ENOMEM;
     412        }
     413
     414        if (data == NULL) {
     415                /* If no event context was available, then create one for this loop */
     416                ev = samba_tevent_context_init(frame);
     417                if (ev == NULL) {
     418                        TALLOC_FREE(frame);
     419                        return ENOMEM;
     420                }
     421        } else {
     422                ev = talloc_get_type_abort(data, struct tevent_context);
     423        }
     424
     425        ret = krb5_krbhst_get_addrinfo(context, hi, &ai);
     426        if (ret) {
     427                TALLOC_FREE(frame);
     428                return ret;
     429        }
     430
     431        ret = smb_krb5_send_and_recv_func_int(context, ev, hi, ai, smb_krb5_send_and_recv_func, data, timeout, send_buf, recv_buf);
     432        TALLOC_FREE(frame);
     433        return ret;
     434}
     435
     436krb5_error_code smb_krb5_send_and_recv_func_forced(krb5_context context,
     437                                                   void *data, /* struct addrinfo */
     438                                                   krb5_krbhst_info *hi,
     439                                                   time_t timeout,
     440                                                   const krb5_data *send_buf,
     441                                                   krb5_data *recv_buf)
     442{
     443        krb5_error_code k5ret;
     444        struct addrinfo *ai = data;
     445
     446        struct tevent_context *ev;
     447        TALLOC_CTX *frame = talloc_stackframe();
     448        if (frame == NULL) {
     449                return ENOMEM;
     450        }
     451
     452        /* no event context is passed in, create one for this loop */
     453        ev = samba_tevent_context_init(frame);
     454        if (ev == NULL) {
     455                TALLOC_FREE(frame);
     456                return ENOMEM;
     457        }
     458
     459        /* No need to pass in send_and_recv functions, we won't nest on this private event loop */
     460        k5ret = smb_krb5_send_and_recv_func_int(context, ev, hi, ai, NULL, NULL,
     461                                                timeout, send_buf, recv_buf);
     462        TALLOC_FREE(frame);
     463        return k5ret;
     464}
     465#endif
    398466
    399467krb5_error_code
     
    403471{
    404472        krb5_error_code ret;
     473#ifdef SAMBA4_USES_HEIMDAL
    405474        char **config_files;
    406475        const char *config_file, *realm;
     476#endif
    407477        krb5_context krb5_ctx;
    408478
     
    416486        }
    417487
    418         config_file = config_path(tmp_ctx, lp_ctx, "krb5.conf");
     488        /* The MIT Kerberos build relies on using the system krb5.conf file.
     489         * If you really want to use another file please set KRB5_CONFIG
     490         * accordingly. */
     491#ifdef SAMBA4_USES_HEIMDAL
     492        config_file = lpcfg_config_path(tmp_ctx, lp_ctx, "krb5.conf");
    419493        if (!config_file) {
    420494                krb5_free_context(krb5_ctx);
     
    423497
    424498        /* Use our local krb5.conf file by default */
    425         ret = krb5_prepend_config_files_default(config_file == NULL?"":config_file, &config_files);
     499        ret = krb5_prepend_config_files_default(config_file, &config_files);
    426500        if (ret) {
    427501                DEBUG(1,("krb5_prepend_config_files_default failed (%s)\n",
     
    450524                }
    451525        }
    452 
     526#endif
    453527        *_krb5_context = krb5_ctx;
    454528        return 0;
     
    456530
    457531krb5_error_code smb_krb5_init_context(void *parent_ctx,
    458                                       struct tevent_context *ev,
    459532                                      struct loadparm_context *lp_ctx,
    460533                                      struct smb_krb5_context **smb_krb5_context)
     
    462535        krb5_error_code ret;
    463536        TALLOC_CTX *tmp_ctx;
     537        krb5_context kctx;
     538#ifdef SAMBA4_USES_HEIMDAL
     539        krb5_log_facility *logf;
     540#endif
    464541
    465542        initialize_krb5_error_table();
     
    473550        }
    474551
    475         ret = smb_krb5_init_context_basic(tmp_ctx, lp_ctx,
    476                                           &(*smb_krb5_context)->krb5_context);
     552        ret = smb_krb5_init_context_basic(tmp_ctx, lp_ctx, &kctx);
    477553        if (ret) {
    478554                DEBUG(1,("smb_krb5_context_init_basic failed (%s)\n",
     
    481557                return ret;
    482558        }
    483 
     559        (*smb_krb5_context)->krb5_context = kctx;
     560
     561        talloc_set_destructor(*smb_krb5_context, smb_krb5_context_destroy);
     562
     563#ifdef SAMBA4_USES_HEIMDAL
    484564        /* TODO: Should we have a different name here? */
    485         ret = krb5_initlog((*smb_krb5_context)->krb5_context, "Samba", &(*smb_krb5_context)->logf);
     565        ret = krb5_initlog(kctx, "Samba", &logf);
    486566
    487567        if (ret) {
    488568                DEBUG(1,("krb5_initlog failed (%s)\n",
    489                          smb_get_krb5_error_message((*smb_krb5_context)->krb5_context, ret, tmp_ctx)));
    490                 krb5_free_context((*smb_krb5_context)->krb5_context);
    491                 talloc_free(tmp_ctx);
    492                 return ret;
    493         }
    494 
    495         talloc_set_destructor(*smb_krb5_context, smb_krb5_context_destroy);
    496 
    497         ret = krb5_addlog_func((*smb_krb5_context)->krb5_context, (*smb_krb5_context)->logf, 0 /* min */, -1 /* max */,
    498                                smb_krb5_debug_wrapper, smb_krb5_debug_close, NULL);
     569                         smb_get_krb5_error_message(kctx, ret, tmp_ctx)));
     570                talloc_free(tmp_ctx);
     571                return ret;
     572        }
     573        (*smb_krb5_context)->pvt_log_data = logf;
     574
     575        ret = krb5_addlog_func(kctx, logf, 0 /* min */, -1 /* max */,
     576                               smb_krb5_debug_wrapper,
     577                                smb_krb5_debug_close, NULL);
    499578        if (ret) {
    500579                DEBUG(1,("krb5_addlog_func failed (%s)\n",
    501                          smb_get_krb5_error_message((*smb_krb5_context)->krb5_context, ret, tmp_ctx)));
    502                 talloc_free(tmp_ctx);
    503                 return ret;
    504         }
    505         krb5_set_warn_dest((*smb_krb5_context)->krb5_context, (*smb_krb5_context)->logf);
    506 
    507         /* Set use of our socket lib */
    508         if (ev) {
    509                 struct tevent_context *previous_ev;
    510                 ret = smb_krb5_context_set_event_ctx(*smb_krb5_context,
    511                                                      ev, &previous_ev);
    512                 if (ret) {
    513                         talloc_free(tmp_ctx);
    514                         return ret;
    515                 }
    516         }
    517 
     580                         smb_get_krb5_error_message(kctx, ret, tmp_ctx)));
     581                talloc_free(tmp_ctx);
     582                return ret;
     583        }
     584        krb5_set_warn_dest(kctx, logf);
     585
     586        /* Set options in kerberos */
     587
     588        krb5_set_dns_canonicalize_hostname(kctx,
     589                        lpcfg_parm_bool(lp_ctx, NULL, "krb5",
     590                                        "set_dns_canonicalize", false));
     591#endif
    518592        talloc_steal(parent_ctx, *smb_krb5_context);
    519593        talloc_free(tmp_ctx);
    520594
    521         /* Set options in kerberos */
    522 
    523         krb5_set_dns_canonicalize_hostname((*smb_krb5_context)->krb5_context,
    524                                            lpcfg_parm_bool(lp_ctx, NULL, "krb5", "set_dns_canonicalize", false));
    525 
    526595        return 0;
    527596}
    528597
     598#ifdef SAMBA4_USES_HEIMDAL
    529599krb5_error_code smb_krb5_context_set_event_ctx(struct smb_krb5_context *smb_krb5_context,
    530600                                               struct tevent_context *ev,
     
    580650        return 0;
    581651}
     652#endif
  • vendor/current/source4/auth/kerberos/krb5_init_context.h

    r740 r988  
    1818*/
    1919
     20#ifndef _KRB5_INIT_CONTEXT_H_
     21#define _KRB5_INIT_CONTEXT_H_
     22
    2023struct smb_krb5_context {
    2124        krb5_context krb5_context;
    22         krb5_log_facility *logf;
     25        void *pvt_log_data;
    2326        struct tevent_context *current_ev;
    2427};
    25        
     28
    2629struct tevent_context;
    2730struct loadparm_context;
     
    3235                            krb5_context *_krb5_context);
    3336
    34 krb5_error_code smb_krb5_init_context(void *parent_ctx, struct tevent_context *ev,
     37krb5_error_code smb_krb5_init_context(void *parent_ctx,
    3538                                      struct loadparm_context *lp_ctx,
    3639                                      struct smb_krb5_context **smb_krb5_context);
    3740
     41#ifdef SAMBA4_USES_HEIMDAL
    3842krb5_error_code smb_krb5_send_and_recv_func(krb5_context context,
    3943                                            void *data,
     
    4246                                            const krb5_data *send_buf,
    4347                                            krb5_data *recv_buf);
     48krb5_error_code smb_krb5_send_and_recv_func_forced(krb5_context context,
     49                                                   void *data, /* struct addrinfo */
     50                                                   krb5_krbhst_info *hi,
     51                                                   time_t timeout,
     52                                                   const krb5_data *send_buf,
     53                                                   krb5_data *recv_buf);
     54krb5_error_code smb_krb5_context_set_event_ctx(struct smb_krb5_context *smb_krb5_context,
     55                                               struct tevent_context *ev,
     56                                               struct tevent_context **previous_ev);
     57krb5_error_code smb_krb5_context_remove_event_ctx(struct smb_krb5_context *smb_krb5_context,
     58                                                  struct tevent_context *previous_ev,
     59                                                  struct tevent_context *ev);
     60#endif
     61
     62#endif /* _KRB5_INIT_CONTEXT_H_ */
  • vendor/current/source4/auth/kerberos/wscript_build

    r740 r988  
    11#!/usr/bin/env python
    22
     3bld.SAMBA_SUBSYSTEM('KRB_INIT_CTX',
     4                    source='krb5_init_context.c',
     5                    deps='gssapi krb5samba'
     6                   )
     7
    38bld.SAMBA_LIBRARY('authkrb5',
    4                   source='kerberos.c clikrb5.c kerberos_heimdal.c kerberos_pac.c gssapi_parse.c krb5_init_context.c keytab_copy.c',
     9                  source='kerberos_pac.c',
    510                  autoproto='proto.h',
    6                   public_deps='krb5 ndr-krb5pac samba_socket LIBCLI_RESOLVE com_err asn1',
    7                   deps='ASN1_UTIL auth_sam_reply tevent LIBPACKET ndr ldb',
     11                  public_deps='ndr-krb5pac krb5samba samba_socket LIBCLI_RESOLVE asn1',
     12                  deps='auth_sam_reply tevent LIBPACKET ndr ldb krb5samba KRB_INIT_CTX KRB5_PAC samba-errors',
    813                  private_library=True
    914                  )
     
    1217        autoproto='kerberos_util.h',
    1318        source='kerberos_util.c',
    14         deps='authkrb5 com_err ldb CREDENTIALS_KRB5 SECRETS',
     19        deps='authkrb5 krb5samba com_err CREDENTIALS_KRB5',
    1520        )
    1621
     22bld.SAMBA_SUBSYSTEM('KERBEROS_SRV_KEYTAB',
     23        autoproto='kerberos_srv_keytab.h',
     24        source='srv_keytab.c',
     25        deps='authkrb5',
     26        )
  • vendor/current/source4/auth/ntlm/auth.c

    r740 r988  
    2727#include "param/param.h"
    2828#include "dsdb/samdb/samdb.h"
    29 
     29#include "libcli/wbclient/wbclient.h"
     30#include "lib/util/samba_modules.h"
     31#include "auth/credentials/credentials.h"
     32#include "system/kerberos.h"
     33#include "auth/kerberos/kerberos.h"
     34#include "auth/kerberos/kerberos_util.h"
     35#include "libds/common/roles.h"
     36
     37static NTSTATUS auth_generate_session_info_wrapper(struct auth4_context *auth_context,
     38                                                   TALLOC_CTX *mem_ctx,
     39                                                  void *server_returned_info,
     40                                                   const char *original_user_name,
     41                                                   uint32_t session_info_flags,
     42                                                   struct auth_session_info **session_info);
    3043
    3144/***************************************************************************
    3245 Set a fixed challenge
    3346***************************************************************************/
    34 _PUBLIC_ NTSTATUS auth_context_set_challenge(struct auth_context *auth_ctx, const uint8_t chal[8], const char *set_by)
     47_PUBLIC_ NTSTATUS auth_context_set_challenge(struct auth4_context *auth_ctx, const uint8_t chal[8], const char *set_by)
    3548{
    3649        auth_ctx->challenge.set_by = talloc_strdup(auth_ctx, set_by);
     
    4154
    4255        return NT_STATUS_OK;
    43 }
    44 
    45 /***************************************************************************
    46  Set a fixed challenge
    47 ***************************************************************************/
    48 _PUBLIC_ bool auth_challenge_may_be_modified(struct auth_context *auth_ctx)
    49 {
    50         return auth_ctx->challenge.may_be_modified;
    5156}
    5257
     
    5560 Returns a const char of length 8 bytes.
    5661****************************************************************************/
    57 _PUBLIC_ NTSTATUS auth_get_challenge(struct auth_context *auth_ctx, uint8_t chal[8])
    58 {
    59         NTSTATUS nt_status;
    60         struct auth_method_context *method;
     62_PUBLIC_ NTSTATUS auth_get_challenge(struct auth4_context *auth_ctx, uint8_t chal[8])
     63{
    6164
    6265        if (auth_ctx->challenge.data.length == 8) {
     
    6770        }
    6871
    69         for (method = auth_ctx->methods; method; method = method->next) {
    70                 nt_status = method->ops->get_challenge(method, auth_ctx, chal);
    71                 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NOT_IMPLEMENTED)) {
    72                         continue;
    73                 }
    74 
    75                 NT_STATUS_NOT_OK_RETURN(nt_status);
    76 
    77                 auth_ctx->challenge.data        = data_blob_talloc(auth_ctx, chal, 8);
    78                 NT_STATUS_HAVE_NO_MEMORY(auth_ctx->challenge.data.data);
    79                 auth_ctx->challenge.set_by      = method->ops->name;
    80 
    81                 break;
    82         }
    83 
    8472        if (!auth_ctx->challenge.set_by) {
    8573                generate_random_buffer(chal, 8);
     
    8876                NT_STATUS_HAVE_NO_MEMORY(auth_ctx->challenge.data.data);
    8977                auth_ctx->challenge.set_by              = "random";
    90 
    91                 auth_ctx->challenge.may_be_modified     = true;
    9278        }
    9379
     
    10490 Supply either a principal or a DN
    10591****************************************************************************/
    106 _PUBLIC_ NTSTATUS auth_get_user_info_dc_principal(TALLOC_CTX *mem_ctx,
    107                                                  struct auth_context *auth_ctx,
    108                                                  const char *principal,
    109                                                  struct ldb_dn *user_dn,
    110                                                  struct auth_user_info_dc **user_info_dc)
     92static NTSTATUS auth_generate_session_info_principal(struct auth4_context *auth_ctx,
     93                                                  TALLOC_CTX *mem_ctx,
     94                                                  const char *principal,
     95                                                  struct ldb_dn *user_dn,
     96                                                  uint32_t session_info_flags,
     97                                                  struct auth_session_info **session_info)
    11198{
    11299        NTSTATUS nt_status;
    113100        struct auth_method_context *method;
     101        struct auth_user_info_dc *user_info_dc;
    114102
    115103        for (method = auth_ctx->methods; method; method = method->next) {
     
    118106                }
    119107
    120                 nt_status = method->ops->get_user_info_dc_principal(mem_ctx, auth_ctx, principal, user_dn, user_info_dc);
     108                nt_status = method->ops->get_user_info_dc_principal(mem_ctx, auth_ctx, principal, user_dn, &user_info_dc);
    121109                if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NOT_IMPLEMENTED)) {
    122110                        continue;
    123111                }
     112                if (!NT_STATUS_IS_OK(nt_status)) {
     113                        return nt_status;
     114                }
     115
     116                nt_status = auth_generate_session_info_wrapper(auth_ctx, mem_ctx,
     117                                                               user_info_dc,
     118                                                               user_info_dc->info->account_name,
     119                                                               session_info_flags, session_info);
     120                talloc_free(user_info_dc);
    124121
    125122                return nt_status;
     
    156153 **/
    157154
    158 _PUBLIC_ NTSTATUS auth_check_password(struct auth_context *auth_ctx,
     155_PUBLIC_ NTSTATUS auth_check_password(struct auth4_context *auth_ctx,
    159156                             TALLOC_CTX *mem_ctx,
    160157                             const struct auth_usersupplied_info *user_info,
     
    188185}
    189186
     187_PUBLIC_ NTSTATUS auth_check_password_wrapper(struct auth4_context *auth_ctx,
     188                                              TALLOC_CTX *mem_ctx,
     189                                              const struct auth_usersupplied_info *user_info,
     190                                              void **server_returned_info,
     191                                              DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key)
     192{
     193        struct auth_user_info_dc *user_info_dc;
     194        NTSTATUS status = auth_check_password(auth_ctx, mem_ctx, user_info, &user_info_dc);
     195
     196        if (NT_STATUS_IS_OK(status)) {
     197                *server_returned_info = user_info_dc;
     198
     199                if (user_session_key) {
     200                        DEBUG(10, ("Got NT session key of length %u\n",
     201                                   (unsigned)user_info_dc->user_session_key.length));
     202                        *user_session_key = user_info_dc->user_session_key;
     203                        talloc_steal(mem_ctx, user_session_key->data);
     204                        user_info_dc->user_session_key = data_blob_null;
     205                }
     206
     207                if (lm_session_key) {
     208                        DEBUG(10, ("Got LM session key of length %u\n",
     209                                   (unsigned)user_info_dc->lm_session_key.length));
     210                        *lm_session_key = user_info_dc->lm_session_key;
     211                        talloc_steal(mem_ctx, lm_session_key->data);
     212                        user_info_dc->lm_session_key = data_blob_null;
     213                }
     214        }
     215
     216        return status;
     217}
     218
    190219struct auth_check_password_state {
    191         struct auth_context *auth_ctx;
     220        struct auth4_context *auth_ctx;
    192221        const struct auth_usersupplied_info *user_info;
    193222        struct auth_user_info_dc *user_info_dc;
     
    226255_PUBLIC_ struct tevent_req *auth_check_password_send(TALLOC_CTX *mem_ctx,
    227256                                struct tevent_context *ev,
    228                                 struct auth_context *auth_ctx,
     257                                struct auth4_context *auth_ctx,
    229258                                const struct auth_usersupplied_info *user_info)
    230259{
     
    252281
    253282        if (!user_info->mapped_state) {
    254                 nt_status = map_user_info(req, lpcfg_workgroup(auth_ctx->lp_ctx),
     283                nt_status = map_user_info(auth_ctx->sam_ctx, req, lpcfg_workgroup(auth_ctx->lp_ctx),
    255284                                          user_info, &user_info_tmp);
    256285                if (tevent_req_nterror(req, nt_status)) {
     
    315344        for (method=state->auth_ctx->methods; method; method = method->next) {
    316345
     346                if (state->user_info->flags & USER_INFO_LOCAL_SAM_ONLY
     347                    && !(method->ops->flags & AUTH_METHOD_LOCAL_SAM)) {
     348                        continue;
     349                }
     350
    317351                /* we fill in state->method here so debug messages in
    318352                   the callers know which method failed */
     
    343377
    344378        if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
    345                 /* don't expose the NT_STATUS_NOT_IMPLEMENTED
    346                    internals */
    347                 status = NT_STATUS_NO_SUCH_USER;
     379                if (!(state->user_info->flags & USER_INFO_LOCAL_SAM_ONLY)) {
     380                        /* don't expose the NT_STATUS_NOT_IMPLEMENTED
     381                         * internals, except when the caller is only probing
     382                         * one method, as they may do the fallback
     383                         */
     384                        status = NT_STATUS_NO_SUCH_USER;
     385                }
    348386        }
    349387
     
    407445}
    408446
     447 /* Wrapper because we don't want to expose all callers to needing to
     448  * know that session_info is generated from the main ldb, and because
     449  * we need to break a depenency loop between the DCE/RPC layer and the
     450  * generation of unix tokens via IRPC */
     451static NTSTATUS auth_generate_session_info_wrapper(struct auth4_context *auth_context,
     452                                                   TALLOC_CTX *mem_ctx,
     453                                                   void *server_returned_info,
     454                                                   const char *original_user_name,
     455                                                  uint32_t session_info_flags,
     456                                                  struct auth_session_info **session_info)
     457{
     458        NTSTATUS status;
     459        struct auth_user_info_dc *user_info_dc = talloc_get_type_abort(server_returned_info, struct auth_user_info_dc);
     460
     461        if (user_info_dc->info->authenticated) {
     462                session_info_flags |= AUTH_SESSION_INFO_AUTHENTICATED;
     463        }
     464
     465        status = auth_generate_session_info(mem_ctx, auth_context->lp_ctx,
     466                                            auth_context->sam_ctx, user_info_dc,
     467                                            session_info_flags, session_info);
     468        if (!NT_STATUS_IS_OK(status)) {
     469                return status;
     470        }
     471
     472        if ((session_info_flags & AUTH_SESSION_INFO_UNIX_TOKEN)
     473            && NT_STATUS_IS_OK(status)) {
     474                status = auth_session_info_fill_unix(auth_context->event_ctx,
     475                                                     auth_context->lp_ctx,
     476                                                     original_user_name, *session_info);
     477                if (!NT_STATUS_IS_OK(status)) {
     478                        TALLOC_FREE(*session_info);
     479                }
     480        }
     481        return status;
     482}
     483
    409484/* Wrapper because we don't want to expose all callers to needing to
    410  * know that session_info is generated from the main ldb */
    411 static NTSTATUS auth_generate_session_info_wrapper(TALLOC_CTX *mem_ctx,
    412                                                    struct auth_context *auth_context,
    413                                                    struct auth_user_info_dc *user_info_dc,
    414                                                    uint32_t session_info_flags,
    415                                                    struct auth_session_info **session_info)
    416 {
    417         return auth_generate_session_info(mem_ctx, auth_context->lp_ctx,
    418                                           auth_context->sam_ctx, user_info_dc,
    419                                           session_info_flags, session_info);
     485 * know anything about the PAC or auth subsystem internal structures
     486 * before we output a struct auth session_info */
     487static NTSTATUS auth_generate_session_info_pac(struct auth4_context *auth_ctx,
     488                                               TALLOC_CTX *mem_ctx,
     489                                               struct smb_krb5_context *smb_krb5_context,
     490                                               DATA_BLOB *pac_blob,
     491                                               const char *principal_name,
     492                                               const struct tsocket_address *remote_address,
     493                                               uint32_t session_info_flags,
     494                                               struct auth_session_info **session_info)
     495{
     496        NTSTATUS status;
     497        struct auth_user_info_dc *user_info_dc;
     498        TALLOC_CTX *tmp_ctx;
     499
     500        if (!pac_blob) {
     501                return auth_generate_session_info_principal(auth_ctx, mem_ctx, principal_name,
     502                                                       NULL, session_info_flags, session_info);
     503        }
     504
     505        tmp_ctx = talloc_named(mem_ctx, 0, "gensec_gssapi_session_info context");
     506        NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
     507
     508        status = kerberos_pac_blob_to_user_info_dc(tmp_ctx,
     509                                                   *pac_blob,
     510                                                   smb_krb5_context->krb5_context,
     511                                                   &user_info_dc, NULL, NULL);
     512        if (!NT_STATUS_IS_OK(status)) {
     513                talloc_free(tmp_ctx);
     514                return status;
     515        }
     516
     517        if (user_info_dc->info->authenticated) {
     518                session_info_flags |= AUTH_SESSION_INFO_AUTHENTICATED;
     519        }
     520
     521        status = auth_generate_session_info_wrapper(auth_ctx, mem_ctx,
     522                                                    user_info_dc,
     523                                                    user_info_dc->info->account_name,
     524                                                    session_info_flags, session_info);
     525        talloc_free(tmp_ctx);
     526        return status;
    420527}
    421528
     
    424531 - Allow the caller to specify the methods to use, including optionally the SAM to use
    425532***************************************************************************/
    426 _PUBLIC_ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char **methods,
     533_PUBLIC_ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char * const *methods,
    427534                                              struct tevent_context *ev,
    428                                               struct messaging_context *msg,
     535                                              struct imessaging_context *msg,
    429536                                              struct loadparm_context *lp_ctx,
    430537                                              struct ldb_context *sam_ctx,
    431                                               struct auth_context **auth_ctx)
     538                                              struct auth4_context **auth_ctx)
    432539{
    433540        int i;
    434         struct auth_context *ctx;
     541        struct auth4_context *ctx;
    435542
    436543        auth4_init();
     
    441548        }
    442549
    443         ctx = talloc(mem_ctx, struct auth_context);
     550        ctx = talloc_zero(mem_ctx, struct auth4_context);
    444551        NT_STATUS_HAVE_NO_MEMORY(ctx);
    445         ctx->challenge.set_by           = NULL;
    446         ctx->challenge.may_be_modified  = false;
    447552        ctx->challenge.data             = data_blob(NULL, 0);
    448553        ctx->methods                    = NULL;
     
    471576                method->auth_ctx        = ctx;
    472577                method->depth           = i;
    473                 DLIST_ADD_END(ctx->methods, method, struct auth_method_context *);
    474         }
    475 
    476         ctx->check_password = auth_check_password;
    477         ctx->get_challenge = auth_get_challenge;
    478         ctx->set_challenge = auth_context_set_challenge;
    479         ctx->challenge_may_be_modified = auth_challenge_may_be_modified;
    480         ctx->get_user_info_dc_principal = auth_get_user_info_dc_principal;
     578                DLIST_ADD_END(ctx->methods, method);
     579        }
     580
     581        ctx->check_ntlm_password = auth_check_password_wrapper;
     582        ctx->get_ntlm_challenge = auth_get_challenge;
     583        ctx->set_ntlm_challenge = auth_context_set_challenge;
    481584        ctx->generate_session_info = auth_generate_session_info_wrapper;
     585        ctx->generate_session_info_pac = auth_generate_session_info_pac;
    482586
    483587        *auth_ctx = ctx;
     
    488592const char **auth_methods_from_lp(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
    489593{
    490         const char **auth_methods = NULL;
     594        char **auth_methods = NULL;
     595
    491596        switch (lpcfg_server_role(lp_ctx)) {
    492597        case ROLE_STANDALONE:
    493                 auth_methods = lpcfg_parm_string_list(mem_ctx, lp_ctx, NULL, "auth methods", "standalone", NULL);
     598                auth_methods = str_list_make(mem_ctx, "anonymous sam_ignoredomain", NULL);
    494599                break;
    495600        case ROLE_DOMAIN_MEMBER:
    496                 auth_methods = lpcfg_parm_string_list(mem_ctx, lp_ctx, NULL, "auth methods", "member server", NULL);
     601                auth_methods = str_list_make(mem_ctx, "anonymous sam winbind", NULL);
    497602                break;
    498         case ROLE_DOMAIN_CONTROLLER:
    499                 auth_methods = lpcfg_parm_string_list(mem_ctx, lp_ctx, NULL, "auth methods", "domain controller", NULL);
     603        case ROLE_DOMAIN_BDC:
     604        case ROLE_DOMAIN_PDC:
     605        case ROLE_ACTIVE_DIRECTORY_DC:
     606                auth_methods = str_list_make(mem_ctx, "anonymous sam_ignoredomain winbind", NULL);
    500607                break;
    501608        }
    502         return auth_methods;
     609        return discard_const_p(const char *, auth_methods);
    503610}
    504611
     
    509616_PUBLIC_ NTSTATUS auth_context_create(TALLOC_CTX *mem_ctx,
    510617                             struct tevent_context *ev,
    511                              struct messaging_context *msg,
     618                             struct imessaging_context *msg,
    512619                             struct loadparm_context *lp_ctx,
    513                              struct auth_context **auth_ctx)
     620                             struct auth4_context **auth_ctx)
    514621{
    515622        NTSTATUS status;
     
    525632        }
    526633        status = auth_context_create_methods(mem_ctx, auth_methods, ev, msg, lp_ctx, NULL, auth_ctx);
    527         talloc_free(tmp_ctx);
    528         return status;
    529 }
    530 
    531 /* Create an auth context from an open LDB.
    532 
    533    This allows us not to re-open the LDB when we need to do a some authentication logic (such as tokenGroups)
    534 
    535  */
    536 NTSTATUS auth_context_create_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct auth_context **auth_ctx)
    537 {
    538         NTSTATUS status;
    539         const char **auth_methods;
    540         struct loadparm_context *lp_ctx = talloc_get_type_abort(ldb_get_opaque(ldb, "loadparm"), struct loadparm_context);
    541         struct tevent_context *ev = ldb_get_event_context(ldb);
    542 
    543         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
    544         if (!tmp_ctx) {
    545                 return NT_STATUS_NO_MEMORY;
    546         }
    547 
    548         auth_methods = auth_methods_from_lp(tmp_ctx, lp_ctx);
    549         if (!auth_methods) {
    550                 return NT_STATUS_INVALID_PARAMETER;
    551         }
    552         status = auth_context_create_methods(mem_ctx, auth_methods, ev, NULL, lp_ctx, ldb, auth_ctx);
    553634        talloc_free(tmp_ctx);
    554635        return status;
     
    621702{
    622703        static const struct auth_critical_sizes critical_sizes = {
    623                 AUTH_INTERFACE_VERSION,
     704                AUTH4_INTERFACE_VERSION,
    624705                sizeof(struct auth_operations),
    625706                sizeof(struct auth_method_context),
    626                 sizeof(struct auth_context),
     707                sizeof(struct auth4_context),
    627708                sizeof(struct auth_usersupplied_info),
    628709                sizeof(struct auth_user_info_dc)
  • vendor/current/source4/auth/ntlm/auth_anonymous.c

    r740 r988  
    2525#include "param/param.h"
    2626
     27_PUBLIC_ NTSTATUS auth4_anonymous_init(void);
     28
    2729/**
    2830 * Return a anonymous logon for anonymous users (username = "")
     
    3840        if (user_info->client.account_name && *user_info->client.account_name) {
    3941                return NT_STATUS_NOT_IMPLEMENTED;
     42        }
     43
     44        switch (user_info->password_state) {
     45        case AUTH_PASSWORD_PLAIN:
     46                if (user_info->password.plaintext != NULL &&
     47                    strlen(user_info->password.plaintext) > 0)
     48                {
     49                        return NT_STATUS_NOT_IMPLEMENTED;
     50                }
     51                break;
     52        case AUTH_PASSWORD_HASH:
     53                if (user_info->password.hash.lanman != NULL) {
     54                        return NT_STATUS_NOT_IMPLEMENTED;
     55                }
     56                if (user_info->password.hash.nt != NULL) {
     57                        return NT_STATUS_NOT_IMPLEMENTED;
     58                }
     59                break;
     60        case AUTH_PASSWORD_RESPONSE:
     61                if (user_info->password.response.lanman.length == 1) {
     62                        if (user_info->password.response.lanman.data[0] != '\0') {
     63                                return NT_STATUS_NOT_IMPLEMENTED;
     64                        }
     65                } else if (user_info->password.response.lanman.length > 1) {
     66                        return NT_STATUS_NOT_IMPLEMENTED;
     67                }
     68                if (user_info->password.response.nt.length > 0) {
     69                        return NT_STATUS_NOT_IMPLEMENTED;
     70                }
     71                break;
    4072        }
    4173
     
    6092static const struct auth_operations anonymous_auth_ops = {
    6193        .name           = "anonymous",
    62         .get_challenge  = auth_get_challenge_not_implemented,
    6394        .want_check     = anonymous_want_check,
    6495        .check_password = anonymous_check_password
    6596};
    6697
    67 _PUBLIC_ NTSTATUS auth_anonymous_init(void)
     98_PUBLIC_ NTSTATUS auth4_anonymous_init(void)
    6899{
    69100        NTSTATUS ret;
  • vendor/current/source4/auth/ntlm/auth_developer.c

    r740 r988  
    2424#include "auth/ntlm/auth_proto.h"
    2525#include "libcli/security/security.h"
     26
     27_PUBLIC_ NTSTATUS auth4_developer_init(void);
    2628
    2729static NTSTATUS name_to_ntstatus_want_check(struct auth_method_context *ctx,
     
    132134static const struct auth_operations name_to_ntstatus_auth_ops = {
    133135        .name           = "name_to_ntstatus",
    134         .get_challenge  = auth_get_challenge_not_implemented,
    135136        .want_check     = name_to_ntstatus_want_check,
    136137        .check_password = name_to_ntstatus_check_password
    137138};
    138139
    139 /**
    140  * Return a 'fixed' challenge instead of a variable one.
    141  *
    142  * The idea of this function is to make packet snifs consistant
    143  * with a fixed challenge, so as to aid debugging.
    144  *
    145  * This module is of no value to end-users.
    146  *
    147  * This module does not actually authenticate the user, but
    148  * just pretenteds to need a specified challenge. 
    149  * This module removes *all* security from the challenge-response system
    150  *
    151  * @return NT_STATUS_UNSUCCESSFUL
    152  **/
    153 static NTSTATUS fixed_challenge_get_challenge(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, uint8_t chal[8])
    154 {
    155         const char *challenge = "I am a teapot";
    156 
    157         memcpy(chal, challenge, 8);
    158 
    159         return NT_STATUS_OK;
    160 }
    161 
    162 static NTSTATUS fixed_challenge_want_check(struct auth_method_context *ctx,
    163                                            TALLOC_CTX *mem_ctx,
    164                                            const struct auth_usersupplied_info *user_info)
    165 {
    166         /* don't handle any users */
    167         return NT_STATUS_NOT_IMPLEMENTED;
    168 }
    169 
    170 static NTSTATUS fixed_challenge_check_password(struct auth_method_context *ctx,
    171                                                TALLOC_CTX *mem_ctx,
    172                                                const struct auth_usersupplied_info *user_info,
    173                                                struct auth_user_info_dc **_user_info_dc)
    174 {
    175         /* don't handle any users */
    176         return NT_STATUS_NO_SUCH_USER;
    177 }
    178 
    179 static const struct auth_operations fixed_challenge_auth_ops = {
    180         .name           = "fixed_challenge",
    181         .get_challenge  = fixed_challenge_get_challenge,
    182         .want_check     = fixed_challenge_want_check,
    183         .check_password = fixed_challenge_check_password
    184 };
    185 
    186 _PUBLIC_ NTSTATUS auth_developer_init(void)
     140_PUBLIC_ NTSTATUS auth4_developer_init(void)
    187141{
    188142        NTSTATUS ret;
     
    194148        }
    195149
    196         ret = auth_register(&fixed_challenge_auth_ops);
    197         if (!NT_STATUS_IS_OK(ret)) {
    198                 DEBUG(0,("Failed to register 'fixed_challenge' auth backend!\n"));
    199                 return ret;
    200         }
    201 
    202150        return ret;
    203151}
  • vendor/current/source4/auth/ntlm/auth_sam.c

    r740 r988  
    3434#include "librpc/gen_ndr/ndr_irpc_c.h"
    3535#include "lib/messaging/irpc.h"
     36#include "libcli/auth/libcli_auth.h"
     37#include "libds/common/roles.h"
     38
     39NTSTATUS auth_sam_init(void);
    3640
    3741extern const char *user_attrs[];
     
    7175 the lanman and NT responses.
    7276****************************************************************************/
    73 static NTSTATUS authsam_password_ok(struct auth_context *auth_context,
     77static NTSTATUS authsam_password_ok(struct auth4_context *auth_context,
    7478                                    TALLOC_CTX *mem_ctx,
    7579                                    uint16_t acct_flags,
     
    126130        }
    127131
    128         if (user_sess_key && user_sess_key->data) {
    129                 talloc_steal(auth_context, user_sess_key->data);
    130         }
    131         if (lm_sess_key && lm_sess_key->data) {
    132                 talloc_steal(auth_context, lm_sess_key->data);
    133         }
    134 
    135132        return NT_STATUS_OK;
    136133}
     
    141138  REPL_SECRET getncchanges extended op to fetch the users secrets
    142139 */
    143 static void auth_sam_trigger_repl_secret(TALLOC_CTX *mem_ctx, struct auth_context *auth_context,
     140static void auth_sam_trigger_repl_secret(struct auth4_context *auth_context,
    144141                                         struct ldb_dn *user_dn)
    145142{
     
    147144        struct drepl_trigger_repl_secret r;
    148145        struct tevent_req *req;
    149 
    150         irpc_handle = irpc_binding_handle_by_name(mem_ctx, auth_context->msg_ctx,
     146        TALLOC_CTX *tmp_ctx;
     147
     148        tmp_ctx = talloc_new(auth_context);
     149        if (tmp_ctx == NULL) {
     150                return;
     151        }
     152
     153        irpc_handle = irpc_binding_handle_by_name(tmp_ctx, auth_context->msg_ctx,
    151154                                                  "dreplsrv",
    152155                                                  &ndr_table_irpc);
    153156        if (irpc_handle == NULL) {
    154157                DEBUG(1,(__location__ ": Unable to get binding handle for dreplsrv\n"));
     158                TALLOC_FREE(tmp_ctx);
    155159                return;
    156160        }
     
    158162        r.in.user_dn = ldb_dn_get_linearized(user_dn);
    159163
    160         req = dcerpc_drepl_trigger_repl_secret_r_send(mem_ctx,
     164        /*
     165         * This seem to rely on the current IRPC implementation,
     166         * which delivers the message in the _send function.
     167         *
     168         * TODO: we need a ONE_WAY IRPC handle and register
     169         * a callback and wait for it to be triggered!
     170         */
     171        req = dcerpc_drepl_trigger_repl_secret_r_send(tmp_ctx,
    161172                                                      auth_context->event_ctx,
    162173                                                      irpc_handle,
     
    165176        /* we aren't interested in a reply */
    166177        talloc_free(req);
    167         talloc_free(irpc_handle);
    168 }
    169 
    170 
    171 static NTSTATUS authsam_authenticate(struct auth_context *auth_context,
    172                                      TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx,
    173                                      struct ldb_dn *domain_dn,
    174                                      struct ldb_message *msg,
    175                                      const struct auth_usersupplied_info *user_info,
    176                                      DATA_BLOB *user_sess_key, DATA_BLOB *lm_sess_key)
    177 {
    178         struct samr_Password *lm_pwd, *nt_pwd;
     178        TALLOC_FREE(tmp_ctx);
     179}
     180
     181
     182/*
     183 * Check that a password is OK, and update badPwdCount if required.
     184 */
     185
     186static NTSTATUS authsam_password_check_and_record(struct auth4_context *auth_context,
     187                                                  TALLOC_CTX *mem_ctx,
     188                                                  struct ldb_dn *domain_dn,
     189                                                  struct ldb_message *msg,
     190                                                  uint16_t acct_flags,
     191                                                  const struct auth_usersupplied_info *user_info,
     192                                                  DATA_BLOB *user_sess_key,
     193                                                  DATA_BLOB *lm_sess_key)
     194{
    179195        NTSTATUS nt_status;
    180 
    181         uint16_t acct_flags = samdb_result_acct_flags(auth_context->sam_ctx, mem_ctx, msg, domain_dn);
    182        
    183         /* Quit if the account was locked out. */
    184         if (acct_flags & ACB_AUTOLOCK) {
    185                 DEBUG(3,("check_sam_security: Account for user %s was locked out.\n",
    186                          user_info->mapped.account_name));
    187                 return NT_STATUS_ACCOUNT_LOCKED_OUT;
    188         }
    189 
    190         /* You can only do an interactive login to normal accounts */
    191         if (user_info->flags & USER_INFO_INTERACTIVE_LOGON) {
    192                 if (!(acct_flags & ACB_NORMAL)) {
    193                         return NT_STATUS_NO_SUCH_USER;
    194                 }
    195         }
    196 
    197         nt_status = samdb_result_passwords(mem_ctx, auth_context->lp_ctx, msg, &lm_pwd, &nt_pwd);
    198         NT_STATUS_NOT_OK_RETURN(nt_status);
     196        NTSTATUS auth_status;
     197        TALLOC_CTX *tmp_ctx;
     198        int i, ret;
     199        int history_len = 0;
     200        struct ldb_context *sam_ctx = auth_context->sam_ctx;
     201        const char * const attrs[] = { "pwdHistoryLength", NULL };
     202        struct ldb_message *dom_msg;
     203        struct samr_Password *lm_pwd;
     204        struct samr_Password *nt_pwd;
     205
     206        tmp_ctx = talloc_new(mem_ctx);
     207        if (tmp_ctx == NULL) {
     208                return NT_STATUS_NO_MEMORY;
     209        }
     210
     211        /*
     212         * This call does more than what it appears to do, it also
     213         * checks for the account lockout.
     214         *
     215         * It is done here so that all parts of Samba that read the
     216         * password refuse to even operate on it if the account is
     217         * locked out, to avoid mistakes like CVE-2013-4496.
     218         */
     219        nt_status = samdb_result_passwords(tmp_ctx, auth_context->lp_ctx,
     220                                           msg, &lm_pwd, &nt_pwd);
     221        if (!NT_STATUS_IS_OK(nt_status)) {
     222                TALLOC_FREE(tmp_ctx);
     223                return nt_status;
     224        }
    199225
    200226        if (lm_pwd == NULL && nt_pwd == NULL) {
    201227                bool am_rodc;
    202228                if (samdb_rodc(auth_context->sam_ctx, &am_rodc) == LDB_SUCCESS && am_rodc) {
    203                         /* we don't have passwords for this
     229                        /*
     230                         * we don't have passwords for this
    204231                         * account. We are an RODC, and this account
    205232                         * may be one for which we either are denied
     
    212239                         * replicate the secrets for this account.
    213240                         */
    214                         auth_sam_trigger_repl_secret(mem_ctx, auth_context, msg->dn);
     241                        auth_sam_trigger_repl_secret(auth_context, msg->dn);
     242                        TALLOC_FREE(tmp_ctx);
    215243                        return NT_STATUS_NOT_IMPLEMENTED;
    216244                }
    217245        }
    218246
    219         nt_status = authsam_password_ok(auth_context, mem_ctx,
    220                                         acct_flags, lm_pwd, nt_pwd,
    221                                         user_info, user_sess_key, lm_sess_key);
    222         NT_STATUS_NOT_OK_RETURN(nt_status);
    223 
    224         nt_status = authsam_account_ok(mem_ctx, auth_context->sam_ctx,
     247        auth_status = authsam_password_ok(auth_context, tmp_ctx,
     248                                          acct_flags,
     249                                          lm_pwd, nt_pwd,
     250                                          user_info,
     251                                          user_sess_key, lm_sess_key);
     252        if (NT_STATUS_IS_OK(auth_status)) {
     253                if (user_sess_key->data) {
     254                        talloc_steal(mem_ctx, user_sess_key->data);
     255                }
     256                if (lm_sess_key->data) {
     257                        talloc_steal(mem_ctx, lm_sess_key->data);
     258                }
     259                TALLOC_FREE(tmp_ctx);
     260                return NT_STATUS_OK;
     261        }
     262        *user_sess_key = data_blob_null;
     263        *lm_sess_key = data_blob_null;
     264
     265        if (!NT_STATUS_EQUAL(auth_status, NT_STATUS_WRONG_PASSWORD)) {
     266                TALLOC_FREE(tmp_ctx);
     267                return auth_status;
     268        }
     269
     270        /*
     271         * We only continue if this was a wrong password
     272         * and we'll always return NT_STATUS_WRONG_PASSWORD
     273         * no matter what error happens.
     274         */
     275
     276        /* pull the domain password property attributes */
     277        ret = dsdb_search_one(sam_ctx, tmp_ctx, &dom_msg, domain_dn, LDB_SCOPE_BASE,
     278                              attrs, 0, "objectClass=domain");
     279        if (ret == LDB_SUCCESS) {
     280                history_len = ldb_msg_find_attr_as_uint(dom_msg, "pwdHistoryLength", 0);
     281        } else if (ret == LDB_ERR_NO_SUCH_OBJECT) {
     282                DEBUG(3,("Couldn't find domain %s: %s!\n",
     283                         ldb_dn_get_linearized(domain_dn),
     284                         ldb_errstring(sam_ctx)));
     285        } else {
     286                DEBUG(3,("error finding domain %s: %s!\n",
     287                         ldb_dn_get_linearized(domain_dn),
     288                         ldb_errstring(sam_ctx)));
     289        }
     290
     291        for (i = 1; i < MIN(history_len, 3); i++) {
     292                static const struct samr_Password zero_hash;
     293                struct samr_Password zero_string_hash;
     294                struct samr_Password zero_string_des_hash;
     295                struct samr_Password *nt_history_pwd = NULL;
     296                struct samr_Password *lm_history_pwd = NULL;
     297                NTTIME pwdLastSet;
     298                struct timeval tv_now;
     299                NTTIME now;
     300                int allowed_period_mins;
     301                NTTIME allowed_period;
     302
     303                nt_status = samdb_result_passwords_from_history(tmp_ctx,
     304                                                        auth_context->lp_ctx,
     305                                                        msg, i,
     306                                                        &lm_history_pwd,
     307                                                        &nt_history_pwd);
     308                if (!NT_STATUS_IS_OK(nt_status)) {
     309                        /*
     310                         * If we don't find element 'i' we won't find
     311                         * 'i+1' ...
     312                         */
     313                        break;
     314                }
     315
     316                /*
     317                 * We choose to avoid any issues
     318                 * around different LM and NT history
     319                 * lengths by only checking the NT
     320                 * history
     321                 */
     322                if (nt_history_pwd == NULL) {
     323                        /*
     324                         * If we don't find element 'i' we won't find
     325                         * 'i+1' ...
     326                         */
     327                        break;
     328                }
     329
     330                /* Skip over all-zero hashes in the history */
     331                if (memcmp(nt_history_pwd->hash, zero_hash.hash,
     332                           sizeof(zero_hash.hash)) == 0) {
     333                        continue;
     334                }
     335
     336                /*
     337                 * This looks odd, but the password_hash module writes this in if
     338                 * (somehow) we didn't have an old NT hash
     339                 */
     340
     341                E_md4hash("", zero_string_hash.hash);
     342                if (memcmp(nt_history_pwd->hash, zero_string_hash.hash, 16) == 0) {
     343                        continue;
     344                }
     345
     346                E_deshash("", zero_string_des_hash.hash);
     347                if (!lm_history_pwd || memcmp(lm_history_pwd->hash, zero_string_des_hash.hash, 16) == 0) {
     348                        lm_history_pwd = NULL;
     349                }
     350
     351                auth_status = authsam_password_ok(auth_context, tmp_ctx,
     352                                                  acct_flags,
     353                                                  lm_history_pwd,
     354                                                  nt_history_pwd,
     355                                                  user_info,
     356                                                  user_sess_key,
     357                                                  lm_sess_key);
     358                if (!NT_STATUS_IS_OK(auth_status)) {
     359                        /*
     360                         * If this was not a correct password, try the next
     361                         * one from the history
     362                         */
     363                        *user_sess_key = data_blob_null;
     364                        *lm_sess_key = data_blob_null;
     365                        continue;
     366                }
     367
     368                if (i != 1) {
     369                        /*
     370                         * The authentication was OK, but not against
     371                         * the previous password, which is stored at index 1.
     372                         *
     373                         * We just return the original wrong password.
     374                         * This skips the update of the bad pwd count,
     375                         * because this is almost certainly user error
     376                         * (or automatic login on a computer using a cached
     377                         * password from before the password change),
     378                         * not an attack.
     379                         */
     380                        TALLOC_FREE(tmp_ctx);
     381                        return NT_STATUS_WRONG_PASSWORD;
     382                }
     383
     384                if (user_info->password_state != AUTH_PASSWORD_RESPONSE) {
     385                        /*
     386                         * The authentication was OK against the previous password,
     387                         * but it's not a NTLM network authentication.
     388                         *
     389                         * We just return the original wrong password.
     390                         * This skips the update of the bad pwd count,
     391                         * because this is almost certainly user error
     392                         * (or automatic login on a computer using a cached
     393                         * password from before the password change),
     394                         * not an attack.
     395                         */
     396                        TALLOC_FREE(tmp_ctx);
     397                        return NT_STATUS_WRONG_PASSWORD;
     398                }
     399
     400                /*
     401                 * If the password was OK, it's a NTLM network authentication
     402                 * and it was the previous password.
     403                 *
     404                 * Now we see if it is within the grace period,
     405                 * so that we don't break cached sessions on other computers
     406                 * before the user can lock and unlock their other screens
     407                 * (resetting their cached password).
     408                 *
     409                 * See http://support.microsoft.com/kb/906305
     410                 * OldPasswordAllowedPeriod ("old password allowed period")
     411                 * is specified in minutes. The default is 60.
     412                 */
     413                allowed_period_mins = lpcfg_old_password_allowed_period(auth_context->lp_ctx);
     414                /*
     415                 * NTTIME uses 100ns units
     416                 */
     417                allowed_period = allowed_period_mins * 60 * 1000*1000*10;
     418                pwdLastSet = samdb_result_nttime(msg, "pwdLastSet", 0);
     419                tv_now = timeval_current();
     420                now = timeval_to_nttime(&tv_now);
     421
     422                if (now < pwdLastSet) {
     423                        /*
     424                         * time jump?
     425                         *
     426                         * We just return the original wrong password.
     427                         * This skips the update of the bad pwd count,
     428                         * because this is almost certainly user error
     429                         * (or automatic login on a computer using a cached
     430                         * password from before the password change),
     431                         * not an attack.
     432                         */
     433                        TALLOC_FREE(tmp_ctx);
     434                        return NT_STATUS_WRONG_PASSWORD;
     435                }
     436
     437                if ((now - pwdLastSet) >= allowed_period) {
     438                        /*
     439                         * The allowed period is over.
     440                         *
     441                         * We just return the original wrong password.
     442                         * This skips the update of the bad pwd count,
     443                         * because this is almost certainly user error
     444                         * (or automatic login on a computer using a cached
     445                         * password from before the password change),
     446                         * not an attack.
     447                         */
     448                        TALLOC_FREE(tmp_ctx);
     449                        return NT_STATUS_WRONG_PASSWORD;
     450                }
     451
     452                /*
     453                 * We finally allow the authentication with the
     454                 * previous password within the allowed period.
     455                 */
     456                if (user_sess_key->data) {
     457                        talloc_steal(mem_ctx, user_sess_key->data);
     458                }
     459                if (lm_sess_key->data) {
     460                        talloc_steal(mem_ctx, lm_sess_key->data);
     461                }
     462
     463                TALLOC_FREE(tmp_ctx);
     464                return auth_status;
     465        }
     466
     467        /*
     468         * If we are not in the allowed period or match an old password,
     469         * we didn't return early. Now update the badPwdCount et al.
     470         */
     471        nt_status = authsam_update_bad_pwd_count(auth_context->sam_ctx,
     472                                                 msg, domain_dn);
     473        if (!NT_STATUS_IS_OK(nt_status)) {
     474                /*
     475                 * We need to return the original
     476                 * NT_STATUS_WRONG_PASSWORD error, so there isn't
     477                 * anything more we can do than write something into
     478                 * the log
     479                 */
     480                DEBUG(0, ("Failed to note bad password for user [%s]: %s\n",
     481                          user_info->mapped.account_name,
     482                          nt_errstr(nt_status)));
     483        }
     484
     485        TALLOC_FREE(tmp_ctx);
     486        return NT_STATUS_WRONG_PASSWORD;
     487}
     488
     489static NTSTATUS authsam_authenticate(struct auth4_context *auth_context,
     490                                     TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx,
     491                                     struct ldb_dn *domain_dn,
     492                                     struct ldb_message *msg,
     493                                     const struct auth_usersupplied_info *user_info,
     494                                     DATA_BLOB *user_sess_key, DATA_BLOB *lm_sess_key)
     495{
     496        NTSTATUS nt_status;
     497        bool interactive = (user_info->password_state == AUTH_PASSWORD_HASH);
     498        uint16_t acct_flags = samdb_result_acct_flags(msg, NULL);
     499        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     500        if (!tmp_ctx) {
     501                return NT_STATUS_NO_MEMORY;
     502        }
     503
     504        /* You can only do an interactive login to normal accounts */
     505        if (user_info->flags & USER_INFO_INTERACTIVE_LOGON) {
     506                if (!(acct_flags & ACB_NORMAL)) {
     507                        TALLOC_FREE(tmp_ctx);
     508                        return NT_STATUS_NO_SUCH_USER;
     509                }
     510        }
     511
     512        nt_status = authsam_password_check_and_record(auth_context, tmp_ctx,
     513                                                      domain_dn, msg, acct_flags,
     514                                                      user_info,
     515                                                      user_sess_key, lm_sess_key);
     516        if (!NT_STATUS_IS_OK(nt_status)) {
     517                TALLOC_FREE(tmp_ctx);
     518                return nt_status;
     519        }
     520
     521        nt_status = authsam_account_ok(tmp_ctx, auth_context->sam_ctx,
    225522                                       user_info->logon_parameters,
    226523                                       domain_dn,
     
    229526                                       user_info->mapped.account_name,
    230527                                       false, false);
    231 
     528        if (!NT_STATUS_IS_OK(nt_status)) {
     529                TALLOC_FREE(tmp_ctx);
     530                return nt_status;
     531        }
     532
     533        nt_status = authsam_logon_success_accounting(auth_context->sam_ctx,
     534                                                     msg, domain_dn,
     535                                                     interactive);
     536        if (!NT_STATUS_IS_OK(nt_status)) {
     537                TALLOC_FREE(tmp_ctx);
     538                return nt_status;
     539        }
     540
     541        if (user_sess_key && user_sess_key->data) {
     542                talloc_steal(mem_ctx, user_sess_key->data);
     543        }
     544        if (lm_sess_key && lm_sess_key->data) {
     545                talloc_steal(mem_ctx, lm_sess_key->data);
     546        }
     547
     548        TALLOC_FREE(tmp_ctx);
    232549        return nt_status;
    233550}
     
    340657                        return NT_STATUS_OK;
    341658
    342                 case ROLE_DOMAIN_CONTROLLER:
     659                case ROLE_ACTIVE_DIRECTORY_DC:
    343660                        if (!is_local_name && !is_my_domain) {
    344661                                DEBUG(6,("authsam_check_password: %s is not one of my local names or domain name (DC)\n",
     
    356673/* Wrapper for the auth subsystem pointer */
    357674static NTSTATUS authsam_get_user_info_dc_principal_wrapper(TALLOC_CTX *mem_ctx,
    358                                                           struct auth_context *auth_context,
     675                                                          struct auth4_context *auth_context,
    359676                                                          const char *principal,
    360677                                                          struct ldb_dn *user_dn,
     
    366683static const struct auth_operations sam_ignoredomain_ops = {
    367684        .name                      = "sam_ignoredomain",
    368         .get_challenge             = auth_get_challenge_not_implemented,
    369685        .want_check                = authsam_ignoredomain_want_check,
    370686        .check_password            = authsam_check_password_internals,
    371         .get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper
     687        .get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper,
     688        .flags                     = AUTH_METHOD_LOCAL_SAM
    372689};
    373690
    374691static const struct auth_operations sam_ops = {
    375692        .name                      = "sam",
    376         .get_challenge             = auth_get_challenge_not_implemented,
    377693        .want_check                = authsam_want_check,
    378694        .check_password            = authsam_check_password_internals,
    379         .get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper
     695        .get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper,
     696        .flags                     = AUTH_METHOD_LOCAL_SAM
    380697};
    381698
    382 _PUBLIC_ NTSTATUS auth_sam_init(void)
     699_PUBLIC_ NTSTATUS auth4_sam_init(void);
     700_PUBLIC_ NTSTATUS auth4_sam_init(void)
    383701{
    384702        NTSTATUS ret;
  • vendor/current/source4/auth/ntlm/auth_simple.c

    r740 r988  
    3131_PUBLIC_ NTSTATUS authenticate_username_pw(TALLOC_CTX *mem_ctx,
    3232                                           struct tevent_context *ev,
    33                                            struct messaging_context *msg,
     33                                           struct imessaging_context *msg,
    3434                                           struct loadparm_context *lp_ctx,
    3535                                           const char *nt4_domain,
     
    3939                                           struct auth_session_info **session_info)
    4040{
    41         struct auth_context *auth_context;
     41        struct auth4_context *auth_context;
    4242        struct auth_usersupplied_info *user_info;
    4343        struct auth_user_info_dc *user_info_dc;
     
    9595                        flags |= AUTH_SESSION_INFO_AUTHENTICATED;
    9696                }
    97                 nt_status = auth_context->generate_session_info(tmp_ctx, auth_context,
     97                nt_status = auth_context->generate_session_info(auth_context,
     98                                                                tmp_ctx,
    9899                                                                user_info_dc,
     100                                                                nt4_username,
    99101                                                                flags,
    100102                                                                session_info);
  • vendor/current/source4/auth/ntlm/auth_unix.c

    r740 r988  
    2929#include "param/param.h"
    3030
     31_PUBLIC_ NTSTATUS auth4_unix_init(void);
     32
    3133/* TODO: look at how to best fill in parms retrieveing a struct passwd info
    3234 * except in case USER_INFO_DONT_CHECK_UNIX_ACCOUNT is set
     
    262264                pam_error = pam_end(*pamh, 0);
    263265                if (pam_error != PAM_SUCCESS) {
    264                         /* no vaild pamh here, can we reliably call pam_strerror ? */
     266                        /* no valid pamh here, can we reliably call pam_strerror ? */
    265267                        DEBUG(4,("smb_pam_start: clean up failed, pam_end gave error %d.\n",
    266268                                 pam_error));
     
    282284                pam_error = pam_end(*pamh, 0);
    283285                if (pam_error != PAM_SUCCESS) {
    284                         /* no vaild pamh here, can we reliably call pam_strerror ? */
     286                        /* no valid pamh here, can we reliably call pam_strerror ? */
    285287                        DEBUG(4,("smb_pam_start: clean up failed, pam_end gave error %d.\n",
    286288                                 pam_error));
     
    302304                pam_error = pam_end(pamh, 0);
    303305                if (pam_error != PAM_SUCCESS) {
    304                         /* no vaild pamh here, can we reliably call pam_strerror ? */
     306                        /* no valid pamh here, can we reliably call pam_strerror ? */
    305307                        DEBUG(4,("smb_pam_end: clean up failed, pam_end gave error %d.\n",
    306308                                 pam_error));
     
    512514        bool ret;
    513515
    514 #ifdef WITH_AFS
    515         if (afs_auth(username, password))
    516                 return NT_STATUS_OK;
    517 #endif /* WITH_AFS */
    518 
    519 #ifdef WITH_DFS
    520         if (dfs_auth(username, password))
    521                 return NT_STATUS_OK;
    522 #endif /* WITH_DFS */
     516
    523517
    524518#ifdef OSF1_ENH_SEC
     
    549543#endif /* ULTRIX_AUTH */
    550544       
    551 #ifdef LINUX_BIGCRYPT
    552         ret = (linux_bigcrypt(password, salt, crypted));
    553         if (ret) {
    554                 return NT_STATUS_OK;
    555         } else {
    556                 return NT_STATUS_WRONG_PASSWORD;
    557         }
    558 #endif /* LINUX_BIGCRYPT */
    559        
    560 #if defined(HAVE_BIGCRYPT) && defined(HAVE_CRYPT) && defined(USE_BOTH_CRYPT_CALLS)
    561        
    562         /*
    563          * Some systems have bigcrypt in the C library but might not
    564          * actually use it for the password hashes (HPUX 10.20) is
    565          * a noteable example. So we try bigcrypt first, followed
    566          * by crypt.
    567          */
    568 
    569         if (strcmp(bigcrypt(password, salt), crypted) == 0)
    570                 return NT_STATUS_OK;
    571         else
    572                 ret = (strcmp((char *)crypt(password, salt), crypted) == 0);
    573         if (ret) {
    574                 return NT_STATUS_OK;
    575         } else {
    576                 return NT_STATUS_WRONG_PASSWORD;
    577         }
    578 #else /* HAVE_BIGCRYPT && HAVE_CRYPT && USE_BOTH_CRYPT_CALLS */
     545       
    579546       
    580547#ifdef HAVE_BIGCRYPT
     
    598565        }
    599566#endif /* HAVE_CRYPT */
    600 #endif /* HAVE_BIGCRYPT && HAVE_CRYPT && USE_BOTH_CRYPT_CALLS */
    601567}
    602568
     
    606572        char *username;
    607573        char *password;
    608         char *pwcopy;
    609574        char *salt;
    610575        char *crypted;
    611576        struct passwd *pws;
    612577        NTSTATUS nt_status;
    613         int level = lpcfg_passwordlevel(lp_ctx);
    614578
    615579        *ret_passwd = NULL;
     
    659623#endif
    660624
    661 #ifdef HAVE_GETPRPWNAM
    662         {
    663                 struct pr_passwd *pr_pw = getprpwnam(pws->pw_name);
    664                 if (pr_pw && pr_pw->ufld.fd_encrypt) {
    665                         crypted = talloc_strdup(ctx, pr_pw->ufld.fd_encrypt);
    666                         NT_STATUS_HAVE_NO_MEMORY(crypted);
    667                 }
    668         }
    669 #endif
    670625
    671626#ifdef HAVE_GETPWANAM
     
    707662#endif
    708663
    709 #if defined(HAVE_TRUNCATED_SALT)
    710         /* crypt on some platforms (HPUX in particular)
    711            won't work with more than 2 salt characters. */
    712         salt[2] = 0;
    713 #endif
    714664
    715665        if (crypted[0] == '\0') {
     
    736686        }
    737687
    738         if ( user_info->flags | USER_INFO_CASE_INSENSITIVE_PASSWORD) {
    739                 return nt_status;
    740         }
    741 
    742         /* if the password was given to us with mixed case then we don't
    743          * need to proceed as we know it hasn't been case modified by the
    744          * client */
    745         if (strhasupper(password) && strhaslower(password)) {
    746                 return nt_status;
    747         }
    748 
    749         /* make a copy of it */
    750         pwcopy = talloc_strdup(ctx, password);
    751         if (!pwcopy)
    752                 return NT_STATUS_NO_MEMORY;
    753 
    754         /* try all lowercase if it's currently all uppercase */
    755         if (strhasupper(pwcopy)) {
    756                 strlower(pwcopy);
    757                 nt_status = password_check(username, pwcopy, crypted, salt);
    758                 if NT_STATUS_IS_OK(nt_status) {
    759                         *ret_passwd = pws;
    760                         return nt_status;
    761                 }
    762         }
    763 
    764         /* give up? */
    765         if (level < 1) {
    766                 return NT_STATUS_WRONG_PASSWORD;
    767         }
    768 
    769         /* last chance - all combinations of up to level chars upper! */
    770         strlower(pwcopy);
    771 
    772 #if 0
    773         if (NT_STATUS_IS_OK(nt_status = string_combinations(pwcopy, password_check, level))) {
    774                 *ret_passwd = pws;
    775                 return nt_status;
    776         }
    777 #endif   
     688        /* we no longer try different case combinations here. The use
     689         * of this code is now web auth, where trying different case
     690         * combinations makes no sense
     691         */
     692
    778693        return NT_STATUS_WRONG_PASSWORD;
    779694}
     
    833748static const struct auth_operations unix_ops = {
    834749        .name           = "unix",
    835         .get_challenge  = auth_get_challenge_not_implemented,
    836750        .want_check     = authunix_want_check,
    837751        .check_password = authunix_check_password
    838752};
    839753
    840 _PUBLIC_ NTSTATUS auth_unix_init(void)
     754_PUBLIC_ NTSTATUS auth4_unix_init(void)
    841755{
    842756        NTSTATUS ret;
  • vendor/current/source4/auth/ntlm/auth_util.c

    r740 r988  
    2626#include "libcli/auth/libcli_auth.h"
    2727#include "param/param.h"
     28#include "auth/ntlm/auth_proto.h"
     29#include "librpc/gen_ndr/drsuapi.h"
     30#include "dsdb/samdb/samdb.h"
    2831
    2932/* this default function can be used by mostly all backends
     
    3942 Create an auth_usersupplied_data structure after appropriate mapping.
    4043****************************************************************************/
    41 
    42 NTSTATUS map_user_info(TALLOC_CTX *mem_ctx,
     44static NTSTATUS map_user_info_cracknames(struct ldb_context *sam_ctx,
     45                                         TALLOC_CTX *mem_ctx,
     46                                         const char *default_domain,
     47                                         const struct auth_usersupplied_info *user_info,
     48                                         struct auth_usersupplied_info **user_info_mapped)
     49{
     50        char *domain;
     51        char *account_name;
     52        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     53        WERROR werr;
     54        struct drsuapi_DsNameInfo1 info1;
     55
     56        DEBUG(5,("map_user_info_cracknames: Mapping user [%s]\\[%s] from workstation [%s]\n",
     57                 user_info->client.domain_name, user_info->client.account_name, user_info->workstation_name));
     58
     59        account_name = talloc_strdup(tmp_ctx, user_info->client.account_name);
     60        if (!account_name) {
     61                talloc_free(tmp_ctx);
     62                return NT_STATUS_NO_MEMORY;
     63        }
     64
     65        /* use cracknames to work out what domain is being
     66           asked for */
     67        if (strchr_m(user_info->client.account_name, '@') != NULL) {
     68                werr = DsCrackNameOneName(sam_ctx, tmp_ctx, 0,
     69                                          DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
     70                                          DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
     71                                          user_info->client.account_name,
     72                                          &info1);
     73                if (!W_ERROR_IS_OK(werr)) {
     74                        DEBUG(2,("map_user_info: Failed cracknames of account '%s'\n",
     75                                 user_info->client.account_name));
     76                        talloc_free(tmp_ctx);
     77                        return werror_to_ntstatus(werr);
     78                }
     79                switch (info1.status) {
     80                case DRSUAPI_DS_NAME_STATUS_OK:
     81                        break;
     82                case DRSUAPI_DS_NAME_STATUS_NOT_FOUND:
     83                        DEBUG(2,("map_user_info: Cracknames of account '%s' -> NOT_FOUND\n",
     84                                 user_info->client.account_name));
     85                        talloc_free(tmp_ctx);
     86                        return NT_STATUS_NO_SUCH_USER;
     87                case DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY:
     88                        DEBUG(2,("map_user_info: Cracknames of account '%s' -> DOMAIN_ONLY\n",
     89                                 user_info->client.account_name));
     90                        talloc_free(tmp_ctx);
     91                        return NT_STATUS_NO_SUCH_USER;
     92                case DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE:
     93                        DEBUG(2,("map_user_info: Cracknames of account '%s' -> NOT_UNIQUE\n",
     94                                 user_info->client.account_name));
     95                        talloc_free(tmp_ctx);
     96                        return NT_STATUS_NO_SUCH_USER;
     97                case DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR:
     98                        DEBUG(2,("map_user_info: Cracknames of account '%s' -> RESOLVE_ERROR\n",
     99                                 user_info->client.account_name));
     100                        talloc_free(tmp_ctx);
     101                        return NT_STATUS_NO_SUCH_USER;
     102                default:
     103                        DEBUG(2,("map_user_info: Cracknames of account '%s' -> unknown error %u\n",
     104                                 user_info->client.account_name, info1.status));
     105                        talloc_free(tmp_ctx);
     106                        return NT_STATUS_NO_SUCH_USER;
     107                }
     108                /* info1.result_name is in DOMAIN\username
     109                 * form, which we need to split up into the
     110                 * user_info_mapped structure
     111                 */
     112                domain = talloc_strdup(tmp_ctx, info1.result_name);
     113                if (domain == NULL) {
     114                        talloc_free(tmp_ctx);
     115                        return NT_STATUS_NO_MEMORY;
     116                }
     117                account_name = strchr_m(domain, '\\');
     118                if (account_name == NULL) {
     119                        DEBUG(2,("map_user_info: Cracknames of account '%s' gave invalid result '%s'\n",
     120                                 user_info->client.account_name, info1.result_name));
     121                        talloc_free(tmp_ctx);
     122                        return NT_STATUS_NO_SUCH_USER;
     123                }
     124                *account_name = 0;
     125                account_name = talloc_strdup(tmp_ctx, account_name+1);
     126                if (account_name == NULL) {
     127                        talloc_free(tmp_ctx);
     128                        return NT_STATUS_NO_MEMORY;
     129                }
     130        } else {
     131                char *domain_name;
     132                if (user_info->client.domain_name && *user_info->client.domain_name) {
     133                        domain_name = talloc_asprintf(tmp_ctx, "%s\\", user_info->client.domain_name);
     134                } else {
     135                        domain_name = talloc_strdup(tmp_ctx, default_domain);
     136                }
     137                if (domain_name == NULL) {
     138                        talloc_free(tmp_ctx);
     139                        return NT_STATUS_NO_MEMORY;
     140                }
     141                werr = DsCrackNameOneName(sam_ctx, mem_ctx, 0,
     142                                          DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
     143                                          DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
     144                                          domain_name,
     145                                          &info1);
     146                if (!W_ERROR_IS_OK(werr)) {
     147                        DEBUG(2,("map_user_info: Failed cracknames of domain '%s'\n",
     148                                 domain_name));
     149                        talloc_free(tmp_ctx);
     150                        return werror_to_ntstatus(werr);
     151                }
     152
     153                /* we use the account_name as-is, but get the
     154                 * domain name from cracknames if possible */
     155                account_name = talloc_strdup(mem_ctx, user_info->client.account_name);
     156                if (account_name == NULL) {
     157                        talloc_free(tmp_ctx);
     158                        return NT_STATUS_NO_MEMORY;
     159                }
     160
     161                switch (info1.status) {
     162                case DRSUAPI_DS_NAME_STATUS_OK:
     163                case DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY:
     164                        domain = talloc_strdup(tmp_ctx, info1.result_name);
     165                        if (domain == NULL) {
     166                                talloc_free(tmp_ctx);
     167                                return NT_STATUS_NO_MEMORY;
     168                        }
     169                        if (domain[strlen_m(domain)-1] == '\\') {
     170                                domain[strlen_m(domain)-1] = 0;
     171                        }
     172                        break;
     173                case DRSUAPI_DS_NAME_STATUS_NOT_FOUND:
     174                        /* the domain is unknown - use the
     175                           default domain */
     176                        domain = talloc_strdup(tmp_ctx, default_domain);
     177                        break;
     178                case DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE:
     179                        DEBUG(2,("map_user_info: Cracknames of domain '%s' -> NOT_UNIQUE\n",
     180                                 domain_name));
     181                        talloc_free(tmp_ctx);
     182                        return NT_STATUS_NO_SUCH_USER;
     183                case DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR:
     184                        DEBUG(2,("map_user_info: Cracknames of domain '%s' -> RESOLVE_ERROR\n",
     185                                 domain_name));
     186                        talloc_free(tmp_ctx);
     187                        return NT_STATUS_NO_SUCH_USER;
     188                default:
     189                        DEBUG(2,("map_user_info: Cracknames of account '%s' -> unknown error %u\n",
     190                                 domain_name, info1.status));
     191                        talloc_free(tmp_ctx);
     192                        return NT_STATUS_NO_SUCH_USER;
     193                }
     194                /* domain and account_name are filled in above */
     195        }
     196
     197        *user_info_mapped = talloc_zero(mem_ctx, struct auth_usersupplied_info);
     198        if (!*user_info_mapped) {
     199                talloc_free(tmp_ctx);
     200                return NT_STATUS_NO_MEMORY;
     201        }
     202        if (!talloc_reference(*user_info_mapped, user_info)) {
     203                talloc_free(tmp_ctx);
     204                return NT_STATUS_NO_MEMORY;
     205        }
     206        **user_info_mapped = *user_info;
     207        (*user_info_mapped)->mapped_state = true;
     208        (*user_info_mapped)->mapped.domain_name = talloc_strdup(*user_info_mapped, domain);
     209        (*user_info_mapped)->mapped.account_name = talloc_strdup(*user_info_mapped, account_name);
     210        talloc_free(tmp_ctx);
     211        if (!(*user_info_mapped)->mapped.domain_name
     212            || !(*user_info_mapped)->mapped.account_name) {
     213                return NT_STATUS_NO_MEMORY;
     214        }
     215
     216        return NT_STATUS_OK;
     217}
     218
     219
     220/****************************************************************************
     221 Create an auth_usersupplied_data structure after appropriate mapping.
     222****************************************************************************/
     223NTSTATUS map_user_info(struct ldb_context *sam_ctx,
     224                       TALLOC_CTX *mem_ctx,
    43225                       const char *default_domain,
    44226                       const struct auth_usersupplied_info *user_info,
    45227                       struct auth_usersupplied_info **user_info_mapped)
    46228{
    47         const char *domain;
     229        char *domain;
    48230        char *account_name;
    49231        char *d;
    50         DEBUG(5,("map_user_info: Mapping user [%s]\\[%s] from workstation [%s]\n",
    51                 user_info->client.domain_name, user_info->client.account_name, user_info->workstation_name));
    52 
    53         account_name = talloc_strdup(mem_ctx, user_info->client.account_name);
     232        TALLOC_CTX *tmp_ctx;
     233
     234        if (sam_ctx != NULL) {
     235                /* if possible, use cracknames to parse the
     236                   domain/account */
     237                return map_user_info_cracknames(sam_ctx, mem_ctx, default_domain, user_info, user_info_mapped);
     238        }
     239
     240        DEBUG(0,("map_user_info: Mapping user [%s]\\[%s] from workstation [%s] default_domain=%s\n",
     241                 user_info->client.domain_name, user_info->client.account_name, user_info->workstation_name,
     242                 default_domain));
     243
     244        tmp_ctx = talloc_new(mem_ctx);
     245
     246        account_name = talloc_strdup(tmp_ctx, user_info->client.account_name);
    54247        if (!account_name) {
     248                talloc_free(tmp_ctx);
    55249                return NT_STATUS_NO_MEMORY;
    56250        }
    57251       
    58         /* don't allow "" as a domain, fixes a Win9X bug
    59            where it doesn't supply a domain for logon script
    60            'net use' commands.                                 */
    61 
    62         /* Split user@realm names into user and realm components.  This is TODO to fix with proper userprincipalname support */
     252        /* don't allow "" as a domain, fixes a Win9X bug where it
     253           doesn't supply a domain for logon script 'net use'
     254           commands.  */
     255
     256        /* Split user@realm names into user and realm components.
     257         * This is TODO to fix with proper userprincipalname
     258         * support */
    63259        if (user_info->client.domain_name && *user_info->client.domain_name) {
    64                 domain = user_info->client.domain_name;
     260                domain = talloc_strdup(tmp_ctx, user_info->client.domain_name);
    65261        } else if (strchr_m(user_info->client.account_name, '@')) {
    66262                d = strchr_m(account_name, '@');
    67263                if (!d) {
     264                        talloc_free(tmp_ctx);
    68265                        return NT_STATUS_INTERNAL_ERROR;
    69266                }
     
    72269                domain = d;
    73270        } else {
    74                 domain = default_domain;
    75         }
    76 
     271                domain = talloc_strdup(tmp_ctx, default_domain);
     272        }
     273
     274        if (domain == NULL) {
     275                talloc_free(tmp_ctx);
     276                return NT_STATUS_NO_MEMORY;
     277        }
    77278        *user_info_mapped = talloc_zero(mem_ctx, struct auth_usersupplied_info);
    78279        if (!*user_info_mapped) {
     280                talloc_free(tmp_ctx);
    79281                return NT_STATUS_NO_MEMORY;
    80282        }
    81283        if (!talloc_reference(*user_info_mapped, user_info)) {
     284                talloc_free(tmp_ctx);
    82285                return NT_STATUS_NO_MEMORY;
    83286        }
     
    86289        (*user_info_mapped)->mapped.domain_name = talloc_strdup(*user_info_mapped, domain);
    87290        (*user_info_mapped)->mapped.account_name = talloc_strdup(*user_info_mapped, account_name);
    88         talloc_free(account_name);
     291        talloc_free(tmp_ctx);
    89292        if (!(*user_info_mapped)->mapped.domain_name
    90293            || !(*user_info_mapped)->mapped.account_name) {
     
    99302****************************************************************************/
    100303
    101 NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth_context *auth_context,
     304NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth4_context *auth_context,
    102305                           enum auth_password_state to_state,
    103306                           const struct auth_usersupplied_info *user_info_in,
     
    148351                                                           user_info_in->client.account_name,
    149352                                                           user_info_in->client.domain_name,
    150                                                            user_info_in->password.hash.nt->hash, &chall_blob,
     353                                                           user_info_in->password.hash.nt->hash,
     354                                                           &chall_blob,
     355                                                           NULL, /* server_timestamp */
    151356                                                           &names_blob,
    152357                                                           &lmv2_response, &ntlmv2_response,
  • vendor/current/source4/auth/ntlm/auth_winbind.c

    r740 r988  
    2525#include "auth/auth.h"
    2626#include "auth/ntlm/auth_proto.h"
    27 #include "auth/auth_sam_reply.h"
    2827#include "librpc/gen_ndr/ndr_winbind_c.h"
    2928#include "lib/messaging/irpc.h"
    3029#include "param/param.h"
    3130#include "nsswitch/libwbclient/wbclient.h"
     31#include "auth/auth_sam_reply.h"
    3232#include "libcli/security/security.h"
    3333
    34 static NTSTATUS get_info3_from_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
    35                                                struct wbcAuthUserInfo *info,
    36                                                struct netr_SamInfo3 *info3)
    37 {
    38         int i, j;
    39         struct samr_RidWithAttribute *rids = NULL;
    40         struct dom_sid *user_sid;
    41         struct dom_sid *group_sid;
    42 
    43         user_sid = (struct dom_sid *)(void *)&info->sids[0].sid;
    44         group_sid = (struct dom_sid *)(void *)&info->sids[1].sid;
    45 
    46         info3->base.last_logon = info->logon_time;
    47         info3->base.last_logoff = info->logoff_time;
    48         info3->base.acct_expiry = info->kickoff_time;
    49         info3->base.last_password_change = info->pass_last_set_time;
    50         info3->base.allow_password_change = info->pass_can_change_time;
    51         info3->base.force_password_change = info->pass_must_change_time;
    52 
    53         info3->base.account_name.string = talloc_strdup(mem_ctx,
    54                                                         info->account_name);
    55         info3->base.full_name.string = talloc_strdup(mem_ctx,
    56                                                      info->full_name);
    57         info3->base.logon_script.string = talloc_strdup(mem_ctx,
    58                                                         info->logon_script);
    59         info3->base.profile_path.string = talloc_strdup(mem_ctx,
    60                                                         info->profile_path);
    61         info3->base.home_directory.string = talloc_strdup(mem_ctx,
    62                                                           info->home_directory);
    63         info3->base.home_drive.string = talloc_strdup(mem_ctx,
    64                                                       info->home_drive);
    65         info3->base.logon_server.string = talloc_strdup(mem_ctx,
    66                                                         info->logon_server);
    67         info3->base.domain.string = talloc_strdup(mem_ctx,
    68                                                   info->domain_name);
    69 
    70         info3->base.logon_count = info->logon_count;
    71         info3->base.bad_password_count = info->bad_password_count;
    72         info3->base.user_flags = info->user_flags;
    73         memcpy(info3->base.key.key, info->user_session_key,
    74                sizeof(info3->base.key.key));
    75         memcpy(info3->base.LMSessKey.key, info->lm_session_key,
    76                sizeof(info3->base.LMSessKey.key));
    77         info3->base.acct_flags = info->acct_flags;
    78         memset(info3->base.unknown, 0, sizeof(info3->base.unknown));
    79 
    80         if (info->num_sids < 2) {
    81                 return NT_STATUS_INVALID_PARAMETER;
    82         }
    83 
    84         dom_sid_split_rid(mem_ctx, user_sid,
    85                           &info3->base.domain_sid,
    86                           &info3->base.rid);
    87         dom_sid_split_rid(mem_ctx, group_sid, NULL,
    88                           &info3->base.primary_gid);
    89 
    90         /* We already handled the first two, now take care of the rest */
    91         info3->base.groups.count = info->num_sids - 2;
    92 
    93         rids = talloc_array(mem_ctx, struct samr_RidWithAttribute,
    94                             info3->base.groups.count);
    95         NT_STATUS_HAVE_NO_MEMORY(rids);
    96 
    97         for (i = 2, j = 0; i < info->num_sids; ++i, ++j) {
    98                 struct dom_sid *tmp_sid;
    99                 tmp_sid = (struct dom_sid *)(void *)&info->sids[1].sid;
    100 
    101                 rids[j].attributes = info->sids[i].attributes;
    102                 dom_sid_split_rid(mem_ctx, tmp_sid,
    103                                   NULL, &rids[j].rid);
    104         }
    105         info3->base.groups.rids = rids;
    106 
    107         return NT_STATUS_OK;
    108 }
    109 
     34_PUBLIC_ NTSTATUS auth4_winbind_init(void);
    11035
    11136static NTSTATUS winbind_want_check(struct auth_method_context *ctx,
     
    212137        s->req.in.validation_level      = 3;
    213138
     139        /* Note: this makes use of nested event loops... */
     140        dcerpc_binding_handle_set_sync_ev(irpc_handle, ctx->auth_ctx->event_ctx);
    214141        status = dcerpc_winbind_SamLogon_r(irpc_handle, s, &s->req);
    215142        NT_STATUS_NOT_OK_RETURN(status);
     
    219146                                                      s->req.in.validation_level,
    220147                                                      &s->req.out.validation,
     148                                                       true, /* This user was authenticated */
    221149                                                      user_info_dc);
    222150        NT_STATUS_NOT_OK_RETURN(status);
     
    239167        wbcErr wbc_status;
    240168        NTSTATUS nt_status;
    241         struct netr_SamInfo3 info3;
     169        struct netr_SamInfo3 *info3;
    242170        union netr_Validation validation;
    243171
     
    266194        params.workstation_name = user_info->workstation_name;
    267195
    268         d_fprintf(stderr, "looking up %s@%s logging in from %s\n",
     196        DEBUG(5,("looking up %s@%s logging in from %s\n",
    269197                  params.account_name, params.domain_name,
    270                   params.workstation_name);
     198                  params.workstation_name));
    271199
    272200        memcpy(params.password.response.challenge,
     
    286214        wbc_status = wbcAuthenticateUserEx(&params, &info, &err);
    287215        if (wbc_status == WBC_ERR_AUTH_ERROR) {
    288                 DEBUG(1, ("error was %s (0x%08x)\nerror message was '%s'\n",
    289                       err->nt_string, err->nt_status, err->display_string));
    290 
     216                if (err) {
     217                        DEBUG(1, ("error was %s (0x%08x)\nerror message was '%s'\n",
     218                              err->nt_string, err->nt_status, err->display_string));
     219                }
    291220                nt_status = NT_STATUS(err->nt_status);
    292221                wbcFreeMemory(err);
     
    295224                DEBUG(1, ("wbcAuthenticateUserEx: failed with %u - %s\n",
    296225                        wbc_status, wbcErrorString(wbc_status)));
     226                if (err) {
     227                        DEBUG(1, ("error was %s (0x%08x)\nerror message was '%s'\n",
     228                              err->nt_string, err->nt_status, err->display_string));
     229                }
    297230                return NT_STATUS_LOGON_FAILURE;
    298231        }
    299         nt_status = get_info3_from_wbcAuthUserInfo(mem_ctx, info, &info3);
     232        info3 = wbcAuthUserInfo_to_netr_SamInfo3(mem_ctx, info);
    300233        wbcFreeMemory(info);
    301         NT_STATUS_NOT_OK_RETURN(nt_status);
    302 
    303         validation.sam3 = &info3;
     234        if (!info3) {
     235                DEBUG(1, ("wbcAuthUserInfo_to_netr_SamInfo3 failed\n"));
     236                return NT_STATUS_NO_MEMORY;
     237        }
     238
     239        validation.sam3 = info3;
    304240        nt_status = make_user_info_dc_netlogon_validation(mem_ctx,
    305                                         user_info->client.account_name,
    306                                         3, &validation, user_info_dc);
     241                                                          user_info->client.account_name,
     242                                                          3, &validation,
     243                                                          true, /* This user was authenticated */
     244                                                          user_info_dc);
    307245        return nt_status;
    308246
     
    311249static const struct auth_operations winbind_ops = {
    312250        .name           = "winbind",
    313         .get_challenge  = auth_get_challenge_not_implemented,
    314251        .want_check     = winbind_want_check,
    315252        .check_password = winbind_check_password
     
    318255static const struct auth_operations winbind_wbclient_ops = {
    319256        .name           = "winbind_wbclient",
    320         .get_challenge  = auth_get_challenge_not_implemented,
    321257        .want_check     = winbind_want_check,
    322258        .check_password = winbind_check_password_wbclient
    323259};
    324260
    325 _PUBLIC_ NTSTATUS auth_winbind_init(void)
     261_PUBLIC_ NTSTATUS auth4_winbind_init(void)
    326262{
    327263        NTSTATUS ret;
  • vendor/current/source4/auth/ntlm/wscript_build

    r740 r988  
    44        source='auth_sam.c',
    55        subsystem='auth4',
    6         init_function='auth_sam_init',
    7         deps='samdb auth4_sam NTLMSSP_COMMON samba-hostconfig'
     6        init_function='auth4_sam_init',
     7        deps='samdb auth4_sam NTLMSSP_COMMON samba-hostconfig RPC_NDR_IRPC MESSAGING'
    88        )
    99
     
    1212        source='auth_anonymous.c',
    1313        subsystem='auth4',
    14         init_function='auth_anonymous_init',
     14        init_function='auth4_anonymous_init',
    1515        deps='talloc'
    16         )
    17 
    18 
    19 bld.SAMBA_MODULE('auth4_server',
    20         source='auth_server.c',
    21         subsystem='auth4',
    22         init_function='auth_server_init',
    23         deps='samba-util LIBCLI_SMB CREDENTIALS_NTLM'
    2416        )
    2517
     
    2820        source='auth_winbind.c',
    2921        subsystem='auth4',
    30         init_function='auth_winbind_init',
     22        init_function='auth4_winbind_init',
    3123        deps='RPC_NDR_WINBIND MESSAGING wbclient'
    3224        )
     
    3628        source='auth_developer.c',
    3729        subsystem='auth4',
    38         init_function='auth_developer_init',
     30        init_function='auth4_developer_init',
    3931        deps='talloc'
    4032        )
     
    4436        source='auth_unix.c',
    4537        subsystem='auth4',
    46         init_function='auth_unix_init',
     38        init_function='auth4_unix_init',
    4739        deps='pam PAM_ERRORS LIBTSOCKET'
    4840        )
     
    5244        source='auth.c auth_util.c auth_simple.c',
    5345        autoproto='auth_proto.h',
    54         deps='samba-util security samdb credentials UTIL_TEVENT',
     46        deps='samba-util samba-security samdb samba-credentials tevent-util LIBWBCLIENT_OLD auth_unix_token samba-modules KERBEROS_UTIL',
    5547        private_library=True
    5648        )
  • vendor/current/source4/auth/pyauth.c

    r740 r988  
    3131#include <tevent.h>
    3232#include "librpc/rpc/pyrpc_util.h"
     33#include "lib/events/events.h"
     34
     35void initauth(void);
    3336
    3437staticforward PyTypeObject PyAuthContext;
    3538
    36 /* There's no Py_ssize_t in 2.4, apparently */
    37 #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 5
    38 typedef int Py_ssize_t;
    39 typedef inquiry lenfunc;
    40 typedef intargfunc ssizeargfunc;
    41 #endif
    42 
    43 #ifndef Py_RETURN_NONE
    44 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
    45 #endif
    46 
    47 static PyObject *py_auth_session_get_security_token(PyObject *self, void *closure)
    48 {
    49         struct auth_session_info *session = py_talloc_get_type(self, struct auth_session_info);
    50         PyObject *py_security_token;
    51         py_security_token = py_return_ndr_struct("samba.dcerpc.security", "token",
    52                                                  session->security_token, session->security_token);
    53         return py_security_token;
    54 }
    55 
    56 static int py_auth_session_set_security_token(PyObject *self, PyObject *value, void *closure)
    57 {
    58         struct auth_session_info *session = py_talloc_get_type(self, struct auth_session_info);
    59         session->security_token = talloc_reference(session, py_talloc_get_ptr(value));
    60         return 0;
    61 }
    62 
    63 static PyObject *py_auth_session_get_session_key(PyObject *self, void *closure)
    64 {
    65         struct auth_session_info *session = py_talloc_get_type(self, struct auth_session_info);
    66         return PyString_FromStringAndSize((char *)session->session_key.data, session->session_key.length);
    67 }
    68 
    69 static int py_auth_session_set_session_key(PyObject *self, PyObject *value, void *closure)
    70 {
    71         DATA_BLOB val;
    72         struct auth_session_info *session = py_talloc_get_type(self, struct auth_session_info);
    73         val.data = (uint8_t *)PyString_AsString(value);
    74         val.length = PyString_Size(value);
    75 
    76         session->session_key = data_blob_talloc(session, val.data, val.length);
    77         return 0;
    78 }
    79 
    80 static PyObject *py_auth_session_get_credentials(PyObject *self, void *closure)
    81 {
    82         struct auth_session_info *session = py_talloc_get_type(self, struct auth_session_info);
    83         PyObject *py_credentials;
    84         /* This is evil, as the credentials are not IDL structures */
    85         py_credentials = py_return_ndr_struct("samba.credentials", "Credentials", session->credentials, session->credentials);
    86         return py_credentials;
    87 }
    88 
    89 static int py_auth_session_set_credentials(PyObject *self, PyObject *value, void *closure)
    90 {
    91         struct auth_session_info *session = py_talloc_get_type(self, struct auth_session_info);
    92         session->credentials = talloc_reference(session, PyCredentials_AsCliCredentials(value));
    93         return 0;
    94 }
    95 
    96 static PyGetSetDef py_auth_session_getset[] = {
    97         { discard_const_p(char, "security_token"), (getter)py_auth_session_get_security_token, (setter)py_auth_session_set_security_token, NULL },
    98         { discard_const_p(char, "session_key"), (getter)py_auth_session_get_session_key, (setter)py_auth_session_set_session_key, NULL },
    99         { discard_const_p(char, "credentials"), (getter)py_auth_session_get_credentials, (setter)py_auth_session_set_credentials, NULL },
    100         { NULL }
    101 };
    102 
    103 static PyTypeObject PyAuthSession = {
    104         .tp_name = "AuthSession",
    105         .tp_basicsize = sizeof(py_talloc_Object),
    106         .tp_flags = Py_TPFLAGS_DEFAULT,
    107         .tp_getset = py_auth_session_getset,
    108 };
    109 
    110 PyObject *PyAuthSession_FromSession(struct auth_session_info *session)
    111 {
    112         return py_talloc_reference(&PyAuthSession, session);
     39static PyObject *PyAuthSession_FromSession(struct auth_session_info *session)
     40{
     41        return py_return_ndr_struct("samba.dcerpc.auth", "session_info", session, session);
    11342}
    11443
     
    208137        }
    209138
    210         ldb_ctx = PyLdb_AsLdbContext(py_ldb);
     139        ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
    211140
    212141        if (py_dn == Py_None) {
    213142                user_dn = NULL;
    214143        } else {
    215                 if (!PyObject_AsDn(ldb_ctx, py_dn, ldb_ctx, &user_dn)) {
     144                if (!pyldb_Object_AsDn(ldb_ctx, py_dn, ldb_ctx, &user_dn)) {
    216145                        talloc_free(mem_ctx);
    217146                        return NULL;
     
    267196}
    268197
    269 static PyObject *PyAuthContext_FromContext(struct auth_context *auth_context)
    270 {
    271         return py_talloc_reference(&PyAuthContext, auth_context);
     198static PyObject *PyAuthContext_FromContext(struct auth4_context *auth_context)
     199{
     200        return pytalloc_reference(&PyAuthContext, auth_context);
    272201}
    273202
     
    276205        PyObject *py_lp_ctx = Py_None;
    277206        PyObject *py_ldb = Py_None;
    278         PyObject *py_messaging_ctx = Py_None;
     207        PyObject *py_imessaging_ctx = Py_None;
    279208        PyObject *py_auth_context = Py_None;
    280209        PyObject *py_methods = Py_None;
    281210        TALLOC_CTX *mem_ctx;
    282         struct auth_context *auth_context;
    283         struct messaging_context *messaging_context = NULL;
     211        struct auth4_context *auth_context;
     212        struct imessaging_context *imessaging_context = NULL;
    284213        struct loadparm_context *lp_ctx;
    285214        struct tevent_context *ev;
    286         struct ldb_context *ldb;
     215        struct ldb_context *ldb = NULL;
    287216        NTSTATUS nt_status;
    288217        const char **methods;
     
    292221        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOOO",
    293222                                         discard_const_p(char *, kwnames),
    294                                          &py_lp_ctx, &py_messaging_ctx, &py_ldb, &py_methods))
     223                                         &py_lp_ctx, &py_imessaging_ctx, &py_ldb, &py_methods))
    295224                return NULL;
    296225
     
    302231
    303232        if (py_ldb != Py_None) {
    304                 ldb = PyLdb_AsLdbContext(py_ldb);
     233                ldb = pyldb_Ldb_AsLdbContext(py_ldb);
    305234        }
    306235
    307236        lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
    308 
    309         ev = tevent_context_init(mem_ctx);
     237        if (lp_ctx == NULL) {
     238                PyErr_NoMemory();
     239                return NULL;
     240        }
     241
     242        ev = s4_event_context_init(mem_ctx);
    310243        if (ev == NULL) {
    311244                PyErr_NoMemory();
     
    313246        }
    314247
    315         if (py_messaging_ctx != Py_None) {
    316                 messaging_context = py_talloc_get_type(py_messaging_ctx, struct messaging_context);
     248        if (py_imessaging_ctx != Py_None) {
     249                imessaging_context = pytalloc_get_type(py_imessaging_ctx, struct imessaging_context);
    317250        }
    318251
    319252        if (py_methods == Py_None && py_ldb == Py_None) {
    320                 nt_status = auth_context_create(mem_ctx, ev, messaging_context, lp_ctx, &auth_context);
     253                nt_status = auth_context_create(mem_ctx, ev, imessaging_context, lp_ctx, &auth_context);
    321254        } else {
    322255                if (py_methods != Py_None) {
     
    330263                }
    331264                nt_status = auth_context_create_methods(mem_ctx, methods, ev,
    332                                                         messaging_context, lp_ctx,
     265                                                        imessaging_context, lp_ctx,
    333266                                                        ldb, &auth_context);
    334267        }
     
    360293static PyTypeObject PyAuthContext = {
    361294        .tp_name = "AuthContext",
    362         .tp_basicsize = sizeof(py_talloc_Object),
    363295        .tp_flags = Py_TPFLAGS_DEFAULT,
    364296        .tp_new = py_auth_context_new,
    365         .tp_basicsize = sizeof(py_talloc_Object),
    366297};
    367298
     
    377308        PyObject *m;
    378309
    379         PyAuthSession.tp_base = PyTalloc_GetObjectType();
    380         if (PyAuthSession.tp_base == NULL)
    381                 return;
    382 
    383         if (PyType_Ready(&PyAuthSession) < 0)
    384                 return;
    385 
    386         PyAuthContext.tp_base = PyTalloc_GetObjectType();
    387         if (PyAuthContext.tp_base == NULL)
    388                 return;
    389 
    390         if (PyType_Ready(&PyAuthContext) < 0)
     310        if (pytalloc_BaseObject_PyType_Ready(&PyAuthContext) < 0)
    391311                return;
    392312
     
    396316                return;
    397317
    398         Py_INCREF(&PyAuthSession);
    399         PyModule_AddObject(m, "AuthSession", (PyObject *)&PyAuthSession);
    400318        Py_INCREF(&PyAuthContext);
    401319        PyModule_AddObject(m, "AuthContext", (PyObject *)&PyAuthContext);
  • vendor/current/source4/auth/pyauth.h

    r740 r988  
    2424#include "auth/session.h"
    2525
    26 #define PyAuthSession_AsSession(obj) py_talloc_get_type(obj, struct auth_session_info)
    27 #define PyAuthSession_Check(obj) PyObject_TypeCheck(obj, &PyAuthSession)
     26#define PyAuthSession_AsSession(obj) pytalloc_get_type(obj, struct auth_session_info)
    2827struct auth_session_info *PyObject_AsSession(PyObject *obj);
    29 PyObject *PyAuthSession_FromSession(struct auth_session_info *session);
    3028
    3129#endif /* _PYAUTH_H */
  • vendor/current/source4/auth/sam.c

    r740 r988  
    4242        "msDS-SupportedEncryptionTypes",        \
    4343        "supplementalCredentials",              \
     44        "msDS-AllowedToDelegateTo",             \
    4445                                                \
    4546        /* passwords */                         \
     
    4748        "unicodePwd",                           \
    4849                                                \
    49         "userAccountControl",                   \
     50        "userAccountControl",                   \
     51        "msDS-User-Account-Control-Computed",   \
    5052        "objectSid",                            \
    5153                                                \
     
    6567
    6668        "logonHours",
     69
     70        /*
     71         * To allow us to zero the badPwdCount and lockoutTime on
     72         * successful logon, without database churn
     73         */
     74        "lockoutTime",
    6775
    6876        /* check 'allowed workstations' */
     
    7684        "homeDrive",
    7785        "lastLogon",
     86        "lastLogonTimestamp",
    7887        "lastLogoff",
    7988        "accountExpires",
     
    8291        "primaryGroupID",
    8392        "memberOf",
     93        "badPasswordTime",
     94        "lmPwdHistory",
     95        "ntPwdHistory",
    8496        NULL,
    8597};
     
    165177        NTTIME acct_expiry;
    166178        NTTIME must_change_time;
    167 
    168         NTTIME now;
     179        struct timeval tv_now = timeval_current();
     180        NTTIME now = timeval_to_nttime(&tv_now);
     181
    169182        DEBUG(4,("authsam_account_ok: Checking SMB password for user %s\n", name_for_logs));
    170183
    171         acct_flags = samdb_result_acct_flags(sam_ctx, mem_ctx, msg, domain_dn);
     184        acct_flags = samdb_result_acct_flags(msg, "msDS-User-Account-Control-Computed");
    172185       
    173186        acct_expiry = samdb_result_account_expires(msg);
     
    193206
    194207        /* Test account expire time */
    195         unix_to_nt_time(&now, time(NULL));
    196208        if (now > acct_expiry) {
    197209                DEBUG(2,("authsam_account_ok: Account for user '%s' has expired.\n", name_for_logs));
     
    221233                bool invalid_ws = true;
    222234                int i;
    223                 const char **workstations = (const char **)str_list_make(mem_ctx, workstation_list, ",");
    224                
     235                char **workstations = str_list_make(mem_ctx, workstation_list, ",");
     236
    225237                for (i = 0; workstations && workstations[i]; i++) {
    226238                        DEBUG(10,("sam_account_ok: checking for workstation match '%s' and '%s'\n",
     
    298310
    299311        tmp_ctx = talloc_new(user_info_dc);
    300         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info_dc, user_info_dc);
     312        if (user_info_dc == NULL) {
     313                TALLOC_FREE(user_info_dc);
     314                return NT_STATUS_NO_MEMORY;
     315        }
    301316
    302317        sids = talloc_array(user_info_dc, struct dom_sid, 2);
    303         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sids, user_info_dc);
     318        if (sids == NULL) {
     319                TALLOC_FREE(user_info_dc);
     320                return NT_STATUS_NO_MEMORY;
     321        }
    304322
    305323        num_sids = 2;
    306324
    307325        account_sid = samdb_result_dom_sid(user_info_dc, msg, "objectSid");
    308         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(account_sid, user_info_dc);
     326        if (account_sid == NULL) {
     327                TALLOC_FREE(user_info_dc);
     328                return NT_STATUS_NO_MEMORY;
     329        }
    309330
    310331        status = dom_sid_split_rid(tmp_ctx, account_sid, &domain_sid, NULL);
     
    322343         * on SamLogon validation info */
    323344        filter = talloc_asprintf(tmp_ctx, "(&(objectClass=group)(!(groupType:1.2.840.113556.1.4.803:=%u))(groupType:1.2.840.113556.1.4.803:=%u))", GROUP_TYPE_BUILTIN_LOCAL_GROUP, GROUP_TYPE_SECURITY_ENABLED);
    324         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(filter, user_info_dc);
     345        if (filter == NULL) {
     346                TALLOC_FREE(user_info_dc);
     347                return NT_STATUS_NO_MEMORY;
     348        }
    325349
    326350        primary_group_string = dom_sid_string(tmp_ctx, &sids[PRIMARY_GROUP_SID_INDEX]);
    327         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(primary_group_string, user_info_dc);
     351        if (primary_group_string == NULL) {
     352                TALLOC_FREE(user_info_dc);
     353                return NT_STATUS_NO_MEMORY;
     354        }
    328355
    329356        primary_group_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", primary_group_string);
    330         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(primary_group_dn, user_info_dc);
     357        if (primary_group_dn == NULL) {
     358                TALLOC_FREE(user_info_dc);
     359                return NT_STATUS_NO_MEMORY;
     360        }
    331361
    332362        primary_group_blob = data_blob_string_const(primary_group_dn);
     
    372402
    373403        info->domain_name = talloc_strdup(info, domain_name);
    374         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->domain_name,
    375                 user_info_dc);
     404        if (info->domain_name == NULL) {
     405                TALLOC_FREE(user_info_dc);
     406                return NT_STATUS_NO_MEMORY;
     407        }
    376408
    377409        str = ldb_msg_find_attr_as_string(msg, "displayName", "");
    378410        info->full_name = talloc_strdup(info, str);
    379         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->full_name, user_info_dc);
     411        if (info->full_name == NULL) {
     412                TALLOC_FREE(user_info_dc);
     413                return NT_STATUS_NO_MEMORY;
     414        }
    380415
    381416        str = ldb_msg_find_attr_as_string(msg, "scriptPath", "");
    382417        info->logon_script = talloc_strdup(info, str);
    383         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->logon_script,
    384                 user_info_dc);
     418        if (info->logon_script == NULL) {
     419                TALLOC_FREE(user_info_dc);
     420                return NT_STATUS_NO_MEMORY;
     421        }
    385422
    386423        str = ldb_msg_find_attr_as_string(msg, "profilePath", "");
    387424        info->profile_path = talloc_strdup(info, str);
    388         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->profile_path,
    389                 user_info_dc);
     425        if (info->profile_path == NULL) {
     426                TALLOC_FREE(user_info_dc);
     427                return NT_STATUS_NO_MEMORY;
     428        }
    390429
    391430        str = ldb_msg_find_attr_as_string(msg, "homeDirectory", "");
    392431        info->home_directory = talloc_strdup(info, str);
    393         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->home_directory,
    394                 user_info_dc);
     432        if (info->home_directory == NULL) {
     433                TALLOC_FREE(user_info_dc);
     434                return NT_STATUS_NO_MEMORY;
     435        }
    395436
    396437        str = ldb_msg_find_attr_as_string(msg, "homeDrive", "");
    397438        info->home_drive = talloc_strdup(info, str);
    398         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->home_drive, user_info_dc);
     439        if (info->home_drive == NULL) {
     440                TALLOC_FREE(user_info_dc);
     441                return NT_STATUS_NO_MEMORY;
     442        }
    399443
    400444        info->logon_server = talloc_strdup(info, netbios_name);
    401         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->logon_server,
    402                 user_info_dc);
     445        if (info->logon_server == NULL) {
     446                TALLOC_FREE(user_info_dc);
     447                return NT_STATUS_NO_MEMORY;
     448        }
    403449
    404450        info->last_logon = samdb_result_nttime(msg, "lastLogon", 0);
     
    417463                0);
    418464
    419         info->acct_flags = samdb_result_acct_flags(sam_ctx, mem_ctx,
    420                                                           msg, domain_dn);
     465        info->acct_flags = samdb_result_acct_flags(msg, "msDS-User-Account-Control-Computed");
    421466
    422467        user_info_dc->user_session_key = data_blob_talloc(user_info_dc,
     
    424469                                                         user_sess_key.length);
    425470        if (user_sess_key.data) {
    426                 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info_dc->user_session_key.data,
    427                                                   user_info_dc);
     471                if (user_info_dc->user_session_key.data == NULL) {
     472                        TALLOC_FREE(user_info_dc);
     473                        return NT_STATUS_NO_MEMORY;
     474                }
    428475        }
    429476        user_info_dc->lm_session_key = data_blob_talloc(user_info_dc,
     
    431478                                                       lm_sess_key.length);
    432479        if (lm_sess_key.data) {
    433                 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info_dc->lm_session_key.data,
    434                                                   user_info_dc);
     480                if (user_info_dc->lm_session_key.data == NULL) {
     481                        TALLOC_FREE(user_info_dc);
     482                        return NT_STATUS_NO_MEMORY;
     483                }
    435484        }
    436485
     
    442491                                                   struct dom_sid,
    443492                                                   user_info_dc->num_sids+1);
    444                 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info_dc->sids, user_info_dc);
     493                if (user_info_dc->sids == NULL) {
     494                        TALLOC_FREE(user_info_dc);
     495                        return NT_STATUS_NO_MEMORY;
     496                }
    445497                user_info_dc->sids[user_info_dc->num_sids] = global_sid_Enterprise_DCs;
    446498                user_info_dc->num_sids++;
     
    454506                                                   struct dom_sid,
    455507                                                   user_info_dc->num_sids+1);
    456                 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info_dc->sids, user_info_dc);
     508                if (user_info_dc->sids == NULL) {
     509                        TALLOC_FREE(user_info_dc);
     510                        return NT_STATUS_NO_MEMORY;
     511                }
    457512                user_info_dc->sids[user_info_dc->num_sids] = *domain_sid;
    458513                sid_append_rid(&user_info_dc->sids[user_info_dc->num_sids],
     
    493548        /* pull the user attributes */
    494549        ret = dsdb_search_one(sam_ctx, tmp_ctx, msg, user_dn,
    495                               LDB_SCOPE_BASE, attrs, DSDB_SEARCH_SHOW_EXTENDED_DN, "(objectClass=*)");
     550                              LDB_SCOPE_BASE, attrs,
     551                              DSDB_SEARCH_SHOW_EXTENDED_DN | DSDB_SEARCH_NO_GLOBAL_CATALOG,
     552                              "(objectClass=*)");
    496553        if (ret != LDB_SUCCESS) {
    497554                talloc_free(tmp_ctx);
     
    540597                /* pull the user attributes */
    541598                ret = dsdb_search_one(sam_ctx, tmp_ctx, &msg, user_dn,
    542                                       LDB_SCOPE_BASE, user_attrs, DSDB_SEARCH_SHOW_EXTENDED_DN, "(objectClass=*)");
     599                                      LDB_SCOPE_BASE, user_attrs,
     600                                      DSDB_SEARCH_SHOW_EXTENDED_DN | DSDB_SEARCH_NO_GLOBAL_CATALOG,
     601                                      "(objectClass=*)");
    543602                if (ret == LDB_ERR_NO_SUCH_OBJECT) {
    544603                        talloc_free(tmp_ctx);
     
    586645        return NT_STATUS_OK;
    587646}
     647
     648NTSTATUS authsam_update_bad_pwd_count(struct ldb_context *sam_ctx,
     649                                      struct ldb_message *msg,
     650                                      struct ldb_dn *domain_dn)
     651{
     652        const char *attrs[] = { "lockoutThreshold",
     653                                "lockOutObservationWindow",
     654                                "lockoutDuration",
     655                                "pwdProperties",
     656                                NULL };
     657        int ret;
     658        NTSTATUS status;
     659        struct ldb_result *domain_res;
     660        struct ldb_message *msg_mod = NULL;
     661        TALLOC_CTX *mem_ctx;
     662
     663        mem_ctx = talloc_new(msg);
     664        if (mem_ctx == NULL) {
     665                return NT_STATUS_NO_MEMORY;
     666        }
     667
     668        ret = dsdb_search_dn(sam_ctx, mem_ctx, &domain_res, domain_dn, attrs, 0);
     669        if (ret != LDB_SUCCESS) {
     670                TALLOC_FREE(mem_ctx);
     671                return NT_STATUS_INTERNAL_DB_CORRUPTION;
     672        }
     673
     674        status = dsdb_update_bad_pwd_count(mem_ctx, sam_ctx,
     675                                           msg, domain_res->msgs[0], &msg_mod);
     676        if (!NT_STATUS_IS_OK(status)) {
     677                TALLOC_FREE(mem_ctx);
     678                return status;
     679        }
     680
     681        if (msg_mod != NULL) {
     682                ret = dsdb_modify(sam_ctx, msg_mod, 0);
     683                if (ret != LDB_SUCCESS) {
     684                        DEBUG(0, ("Failed to update badPwdCount, badPasswordTime or set lockoutTime on %s: %s\n",
     685                                  ldb_dn_get_linearized(msg_mod->dn), ldb_errstring(sam_ctx)));
     686                        TALLOC_FREE(mem_ctx);
     687                        return NT_STATUS_INTERNAL_ERROR;
     688                }
     689        }
     690
     691        TALLOC_FREE(mem_ctx);
     692        return NT_STATUS_OK;
     693}
     694
     695
     696static NTSTATUS authsam_update_lastlogon_timestamp(struct ldb_context *sam_ctx,
     697                                            struct ldb_message *msg_mod,
     698                                            struct ldb_dn *domain_dn,
     699                                            NTTIME old_timestamp,
     700                                            NTTIME now)
     701{
     702        /*
     703         * We only set lastLogonTimestamp if the current value is older than
     704         * now - msDS-LogonTimeSyncInterval days.
     705         *
     706         * msDS-LogonTimeSyncInterval is an int32_t number of days, while
     707         * lastLogonTimestamp is in the 64 bit 100ns NTTIME format.
     708         *
     709         * The docs say: "the initial update, after the domain functional
     710         * level is raised to DS_BEHAVIOR_WIN2003 or higher, is calculated as
     711         * 14 days minus a random percentage of 5 days", but we aren't doing
     712         * that. The blogosphere seems to think that this randomised update
     713         * happens everytime, but [MS-ADA1] doesn't agree.
     714         *
     715         * Dochelp referred us to the following blog post:
     716         * http://blogs.technet.com/b/askds/archive/2009/04/15/the-lastlogontimestamp-attribute-what-it-was-designed-for-and-how-it-works.aspx
     717         *
     718         * en msDS-LogonTimeSyncInterval is zero, the lastLogonTimestamp is
     719         * not changed.
     720         */
     721        static const char *attrs[] = { "msDS-LogonTimeSyncInterval",
     722                                        NULL };
     723        int ret;
     724        struct ldb_result *domain_res = NULL;
     725        TALLOC_CTX *mem_ctx = NULL;
     726        int32_t sync_interval;
     727        NTTIME sync_interval_nt;
     728
     729        mem_ctx = talloc_new(msg_mod);
     730        if (mem_ctx == NULL) {
     731                return NT_STATUS_NO_MEMORY;
     732        }
     733
     734        ret = dsdb_search_dn(sam_ctx, mem_ctx, &domain_res, domain_dn, attrs,
     735                             0);
     736        if (ret != LDB_SUCCESS || domain_res->count != 1) {
     737                TALLOC_FREE(mem_ctx);
     738                return NT_STATUS_INTERNAL_DB_CORRUPTION;
     739        }
     740
     741        sync_interval = ldb_msg_find_attr_as_int(domain_res->msgs[0],
     742                                                 "msDS-LogonTimeSyncInterval",
     743                                                 14);
     744        DEBUG(5, ("sync interval is %d\n", sync_interval));
     745        if (sync_interval == 0){
     746                /*
     747                 * Setting msDS-LogonTimeSyncInterval to zero is how you ask
     748                 * that nothing happens here.
     749                 */
     750                TALLOC_FREE(mem_ctx);
     751                return NT_STATUS_OK;
     752        }
     753        else if (sync_interval >= 5){
     754                /*
     755                 * Subtract "a random percentage of 5" days. Presumably this
     756                 * percentage is between 0 and 100, and modulus is accurate
     757                 * enough.
     758                 */
     759                uint32_t r = generate_random() % 6;
     760                sync_interval -= r;
     761                DEBUG(5, ("randomised sync interval is %d (-%d)\n", sync_interval, r));
     762        }
     763        /* In the case where sync_interval < 5 there is no randomisation */
     764
     765        sync_interval_nt = sync_interval * 24LL * 3600LL * 10000000LL;
     766
     767        DEBUG(5, ("old timestamp is %lld, threshold %lld, diff %lld\n",
     768                  (long long int)old_timestamp,
     769                  (long long int)(now - sync_interval_nt),
     770                  (long long int)(old_timestamp - now + sync_interval_nt)));
     771
     772        if (old_timestamp > now){
     773                DEBUG(0, ("lastLogonTimestamp is in the future! (%lld > %lld)\n",
     774                          (long long int)old_timestamp, (long long int)now));
     775                /* then what? */
     776
     777        } else if (old_timestamp < now - sync_interval_nt){
     778                DEBUG(5, ("updating lastLogonTimestamp to %lld\n",
     779                          (long long int)now));
     780
     781                /* The time has come to update lastLogonTimestamp */
     782                ret = samdb_msg_add_int64(sam_ctx, msg_mod, msg_mod,
     783                                          "lastLogonTimestamp", now);
     784
     785                if (ret != LDB_SUCCESS) {
     786                        TALLOC_FREE(mem_ctx);
     787                        return NT_STATUS_NO_MEMORY;
     788                }
     789        }
     790        TALLOC_FREE(mem_ctx);
     791        return NT_STATUS_OK;
     792}
     793
     794
     795
     796/* Reset the badPwdCount to zero and update the lastLogon time. */
     797NTSTATUS authsam_logon_success_accounting(struct ldb_context *sam_ctx,
     798                                          const struct ldb_message *msg,
     799                                          struct ldb_dn *domain_dn,
     800                                          bool interactive_or_kerberos)
     801{
     802        int ret;
     803        NTSTATUS status;
     804        int badPwdCount;
     805        int64_t lockoutTime;
     806        struct ldb_message *msg_mod;
     807        TALLOC_CTX *mem_ctx;
     808        struct timeval tv_now;
     809        NTTIME now;
     810        NTTIME lastLogonTimestamp;
     811        NTTIME lastLogon;
     812
     813        lockoutTime = ldb_msg_find_attr_as_int64(msg, "lockoutTime", 0);
     814        badPwdCount = ldb_msg_find_attr_as_int(msg, "badPwdCount", 0);
     815        lastLogonTimestamp = \
     816                ldb_msg_find_attr_as_int64(msg, "lastLogonTimestamp", 0);
     817        lastLogon = ldb_msg_find_attr_as_int64(msg, "lastLogon", 0);
     818
     819        DEBUG(5, ("lastLogonTimestamp is %lld\n",
     820                  (long long int)lastLogonTimestamp));
     821
     822        mem_ctx = talloc_new(msg);
     823        if (mem_ctx == NULL) {
     824                return NT_STATUS_NO_MEMORY;
     825        }
     826        msg_mod = ldb_msg_new(mem_ctx);
     827        if (msg_mod == NULL) {
     828                TALLOC_FREE(mem_ctx);
     829                return NT_STATUS_NO_MEMORY;
     830        }
     831        msg_mod->dn = msg->dn;
     832
     833        if (lockoutTime != 0) {
     834                /*
     835                 * This implies "badPwdCount" = 0, see samldb_lockout_time()
     836                 */
     837                ret = samdb_msg_add_int(sam_ctx, msg_mod, msg_mod, "lockoutTime", 0);
     838                if (ret != LDB_SUCCESS) {
     839                        TALLOC_FREE(mem_ctx);
     840                        return NT_STATUS_NO_MEMORY;
     841                }
     842        } else if (badPwdCount != 0) {
     843                ret = samdb_msg_add_int(sam_ctx, msg_mod, msg_mod, "badPwdCount", 0);
     844                if (ret != LDB_SUCCESS) {
     845                        TALLOC_FREE(mem_ctx);
     846                        return NT_STATUS_NO_MEMORY;
     847                }
     848        }
     849
     850        tv_now = timeval_current();
     851        now = timeval_to_nttime(&tv_now);
     852
     853        if (interactive_or_kerberos || lastLogon == 0 ||
     854            (badPwdCount != 0 && lockoutTime == 0)) {
     855                ret = samdb_msg_add_int64(sam_ctx, msg_mod, msg_mod,
     856                                          "lastLogon", now);
     857                if (ret != LDB_SUCCESS) {
     858                        TALLOC_FREE(mem_ctx);
     859                        return NT_STATUS_NO_MEMORY;
     860                }
     861        }
     862        status = authsam_update_lastlogon_timestamp(sam_ctx, msg_mod, domain_dn,
     863                                                    lastLogonTimestamp, now);
     864        if (!NT_STATUS_IS_OK(status)) {
     865                TALLOC_FREE(mem_ctx);
     866                return NT_STATUS_NO_MEMORY;
     867        }
     868
     869        if (msg_mod->num_elements > 0) {
     870                ret = dsdb_replace(sam_ctx, msg_mod, 0);
     871                if (ret != LDB_SUCCESS) {
     872                        DEBUG(0, ("Failed to set badPwdCount and lockoutTime "
     873                                  "to 0 and/or  lastlogon to now (%lld) "
     874                                  "%s: %s\n", (long long int)now,
     875                                  ldb_dn_get_linearized(msg_mod->dn),
     876                                  ldb_errstring(sam_ctx)));
     877                        TALLOC_FREE(mem_ctx);
     878                        return NT_STATUS_INTERNAL_ERROR;
     879                }
     880        }
     881        TALLOC_FREE(mem_ctx);
     882        return NT_STATUS_OK;
     883}
  • vendor/current/source4/auth/samba_server_gensec.c

    r740 r988  
    3030NTSTATUS samba_server_gensec_start(TALLOC_CTX *mem_ctx,
    3131                                   struct tevent_context *event_ctx,
    32                                    struct messaging_context *msg_ctx,
     32                                   struct imessaging_context *msg_ctx,
    3333                                   struct loadparm_context *lp_ctx,
    3434                                   struct cli_credentials *server_credentials,
     
    3838        NTSTATUS nt_status;
    3939        struct gensec_security *gensec_ctx;
    40         struct auth_context *auth_context;
     40        struct auth4_context *auth_context;
    4141
    4242        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     
    5858
    5959        nt_status = gensec_server_start(tmp_ctx,
    60                                         event_ctx,
    6160                                        lpcfg_gensec_settings(mem_ctx, lp_ctx),
    6261                                        auth_context,
  • vendor/current/source4/auth/session.c

    r740 r988  
    3333#include "system/kerberos.h"
    3434#include <gssapi/gssapi.h>
     35#include "libcli/wbclient/wbclient.h"
    3536
    3637_PUBLIC_ struct auth_session_info *anonymous_session(TALLOC_CTX *mem_ctx,
     
    6566        NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
    6667
    67         session_info = talloc(tmp_ctx, struct auth_session_info);
    68         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(session_info, tmp_ctx);
     68        session_info = talloc_zero(tmp_ctx, struct auth_session_info);
     69        if (session_info == NULL) {
     70                TALLOC_FREE(tmp_ctx);
     71                return NT_STATUS_NO_MEMORY;
     72        }
    6973
    7074        session_info->info = talloc_reference(session_info, user_info_dc->info);
    7175
    7276        session_info->torture = talloc_zero(session_info, struct auth_user_info_torture);
    73         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(session_info->torture, tmp_ctx);
     77        if (session_info->torture == NULL) {
     78                TALLOC_FREE(tmp_ctx);
     79                return NT_STATUS_NO_MEMORY;
     80        }
    7481        session_info->torture->num_dc_sids = user_info_dc->num_sids;
    7582        session_info->torture->dc_sids = talloc_reference(session_info, user_info_dc->sids);
    76         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(session_info->torture->dc_sids, tmp_ctx);
     83        if (session_info->torture->dc_sids == NULL) {
     84                TALLOC_FREE(tmp_ctx);
     85                return NT_STATUS_NO_MEMORY;
     86        }
    7787
    7888        /* unless set otherwise, the session key is the user session
     
    8090        session_info->session_key = data_blob_talloc(session_info, user_info_dc->user_session_key.data, user_info_dc->user_session_key.length);
    8191        if (!session_info->session_key.data && session_info->session_key.length) {
    82                 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(session_info->session_key.data, tmp_ctx);
     92                if (session_info->session_key.data == NULL) {
     93                        TALLOC_FREE(tmp_ctx);
     94                        return NT_STATUS_NO_MEMORY;
     95                }
    8396        }
    8497
    8598        anonymous_sid = dom_sid_parse_talloc(tmp_ctx, SID_NT_ANONYMOUS);
    86         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(anonymous_sid, tmp_ctx);
     99        if (anonymous_sid == NULL) {
     100                TALLOC_FREE(tmp_ctx);
     101                return NT_STATUS_NO_MEMORY;
     102        }
    87103
    88104        system_sid = dom_sid_parse_talloc(tmp_ctx, SID_NT_SYSTEM);
    89         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(system_sid, tmp_ctx);
     105        if (system_sid == NULL) {
     106                TALLOC_FREE(tmp_ctx);
     107                return NT_STATUS_NO_MEMORY;
     108        }
    90109
    91110        sids = talloc_array(tmp_ctx, struct dom_sid, user_info_dc->num_sids);
    92         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sids, tmp_ctx);
     111        if (sids == NULL) {
     112                TALLOC_FREE(tmp_ctx);
     113                return NT_STATUS_NO_MEMORY;
     114        }
    93115        if (!sids) {
    94116                talloc_free(tmp_ctx);
     
    102124        }
    103125
    104         if (user_info_dc->num_sids > PRIMARY_USER_SID_INDEX && dom_sid_equal(anonymous_sid, &user_info_dc->sids[PRIMARY_USER_SID_INDEX])) {
     126        /*
     127         * Finally add the "standard" sids.
     128         * The only difference between guest and "anonymous"
     129         * is the addition of Authenticated_Users.
     130         */
     131
     132        if (session_info_flags & AUTH_SESSION_INFO_DEFAULT_GROUPS) {
     133                sids = talloc_realloc(tmp_ctx, sids, struct dom_sid, num_sids + 2);
     134                NT_STATUS_HAVE_NO_MEMORY(sids);
     135
     136                if (!dom_sid_parse(SID_WORLD, &sids[num_sids])) {
     137                        return NT_STATUS_INTERNAL_ERROR;
     138                }
     139                num_sids++;
     140
     141                if (!dom_sid_parse(SID_NT_NETWORK, &sids[num_sids])) {
     142                        return NT_STATUS_INTERNAL_ERROR;
     143                }
     144                num_sids++;
     145        }
     146
     147        if (session_info_flags & AUTH_SESSION_INFO_AUTHENTICATED) {
     148                sids = talloc_realloc(tmp_ctx, sids, struct dom_sid, num_sids + 1);
     149                NT_STATUS_HAVE_NO_MEMORY(sids);
     150
     151                if (!dom_sid_parse(SID_NT_AUTHENTICATED_USERS, &sids[num_sids])) {
     152                        return NT_STATUS_INTERNAL_ERROR;
     153                }
     154                num_sids++;
     155        }
     156
     157
     158
     159        if (num_sids > PRIMARY_USER_SID_INDEX && dom_sid_equal(anonymous_sid, &sids[PRIMARY_USER_SID_INDEX])) {
    105160                /* Don't expand nested groups of system, anonymous etc*/
    106         } else if (user_info_dc->num_sids > PRIMARY_USER_SID_INDEX && dom_sid_equal(system_sid, &user_info_dc->sids[PRIMARY_USER_SID_INDEX])) {
     161        } else if (num_sids > PRIMARY_USER_SID_INDEX && dom_sid_equal(system_sid, &sids[PRIMARY_USER_SID_INDEX])) {
    107162                /* Don't expand nested groups of system, anonymous etc*/
    108163        } else if (sam_ctx) {
     
    111166
    112167                /* Search for each group in the token */
    113                 for (i = 0; i < user_info_dc->num_sids; i++) {
     168                for (i = 0; i < num_sids; i++) {
    114169                        char *sid_string;
    115170                        const char *sid_dn;
    116171                        DATA_BLOB sid_blob;
    117                        
     172
    118173                        sid_string = dom_sid_string(tmp_ctx,
    119                                                       &user_info_dc->sids[i]);
    120                         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_string, user_info_dc);
     174                                                      &sids[i]);
     175                        if (sid_string == NULL) {
     176                                TALLOC_FREE(user_info_dc);
     177                                return NT_STATUS_NO_MEMORY;
     178                        }
    121179                       
    122180                        sid_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", sid_string);
    123181                        talloc_free(sid_string);
    124                         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_dn, user_info_dc);
     182                        if (sid_dn == NULL) {
     183                                TALLOC_FREE(user_info_dc);
     184                                return NT_STATUS_NO_MEMORY;
     185                        }
    125186                        sid_blob = data_blob_string_const(sid_dn);
    126187                       
     
    146207                                          session_info_flags,
    147208                                          &session_info->security_token);
    148         NT_STATUS_NOT_OK_RETURN_AND_FREE(nt_status, tmp_ctx);
     209        if (!NT_STATUS_IS_OK(nt_status)) {
     210                TALLOC_FREE(tmp_ctx);
     211                return nt_status;
     212        }
    149213
    150214        session_info->credentials = NULL;
     
    156220}
    157221
    158 /* Create a session_info structure from the
    159  * auth_session_info_transport we were forwarded over named pipe
    160  * forwarding.
     222
     223/* Fill out the auth_session_info with a cli_credentials based on the
     224 * auth_session_info we were forwarded over named pipe forwarding.
    161225 *
    162226 * NOTE: The stucture members of session_info_transport are stolen
     
    169233{
    170234        struct auth_session_info *session_info;
    171         session_info = talloc_zero(mem_ctx, struct auth_session_info);
    172         if (!session_info) {
    173                 *reason = "failed to allocate session_info";
    174                 return NULL;
    175         }
    176 
    177         session_info->security_token = talloc_move(session_info, &session_info_transport->security_token);
    178         session_info->info = talloc_move(session_info, &session_info_transport->info);
    179         session_info->session_key = session_info_transport->session_key;
    180         session_info->session_key.data = talloc_move(session_info, &session_info_transport->session_key.data);
    181 
     235        session_info = talloc_steal(mem_ctx, session_info_transport->session_info);
     236        /*
     237         * This is to allow us to check the type of this pointer using
     238         * talloc_get_type()
     239         */
     240        talloc_set_name(session_info, "struct auth_session_info");
     241#ifdef HAVE_GSS_IMPORT_CRED
    182242        if (session_info_transport->exported_gssapi_credentials.length) {
    183243                struct cli_credentials *creds;
     
    230290
    231291        }
    232 
     292#endif
    233293        return session_info;
    234294}
     
    237297/* Create a auth_session_info_transport from an auth_session_info.
    238298 *
    239  * NOTE: Members of the auth_session_info_transport structure are not talloc_referenced, but simply assigned.  They are only valid for the lifetime of the struct auth_session_info
    240  *
    241  * This isn't normally an issue, as the auth_session_info has a very long typical life
     299 * NOTE: Members of the auth_session_info_transport structure are
     300 * talloc_referenced() into this structure, and should not be changed.
    242301 */
    243302NTSTATUS auth_session_info_transport_from_session(TALLOC_CTX *mem_ctx,
     
    248307{
    249308
    250         struct auth_session_info_transport *session_info_transport = talloc_zero(mem_ctx, struct auth_session_info_transport);
    251         session_info_transport->security_token = talloc_reference(session_info, session_info->security_token);
    252         NT_STATUS_HAVE_NO_MEMORY(session_info_transport->security_token);
    253 
    254         session_info_transport->info = talloc_reference(session_info, session_info->info);
    255         NT_STATUS_HAVE_NO_MEMORY(session_info_transport->info);
    256 
    257         session_info_transport->session_key = session_info->session_key;
    258         session_info_transport->session_key.data = talloc_reference(session_info, session_info->session_key.data);
    259         if (!session_info_transport->session_key.data && session_info->session_key.length) {
    260                 return NT_STATUS_NO_MEMORY;
    261         }
    262 
     309        struct auth_session_info_transport *session_info_transport
     310                = talloc_zero(mem_ctx, struct auth_session_info_transport);
     311        if (!session_info_transport) {
     312                return NT_STATUS_NO_MEMORY;
     313        };
     314        session_info_transport->session_info = talloc_reference(session_info_transport, session_info);
     315        if (!session_info_transport->session_info) {
     316                return NT_STATUS_NO_MEMORY;
     317        };
     318#ifdef HAVE_GSS_EXPORT_CRED
    263319        if (session_info->credentials) {
    264320                struct gssapi_creds_container *gcc;
     
    294350                }
    295351        }
     352#endif
    296353        *transport_out = session_info_transport;
    297354        return NT_STATUS_OK;
     
    350407        security_token_debug(0, dbg_lev, session_info->security_token);
    351408}
    352 
  • vendor/current/source4/auth/system_session.c

    r740 r988  
    191191
    192192        user_info_dc->sids[PRIMARY_GROUP_SID_INDEX] = *domain_sid;
    193         sid_append_rid(&user_info_dc->sids[PRIMARY_USER_SID_INDEX], DOMAIN_RID_USERS);
     193        sid_append_rid(&user_info_dc->sids[PRIMARY_GROUP_SID_INDEX], DOMAIN_RID_USERS);
    194194
    195195        user_info_dc->sids[2] = global_sid_Builtin_Administrators;
     
    268268        struct auth_user_info_dc *user_info_dc = NULL;
    269269        TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);
     270
     271        NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
    270272
    271273        nt_status = auth_domain_admin_user_info_dc(mem_ctx, lpcfg_netbios_name(lp_ctx),
  • vendor/current/source4/auth/wscript_build

    r740 r988  
    33bld.RECURSE('gensec')
    44bld.RECURSE('kerberos')
    5 bld.RECURSE('ntlmssp')
    65bld.RECURSE('ntlm')
    7 bld.RECURSE('credentials')
    86
    97bld.SAMBA_SUBSYSTEM('auth_session',
    108        source='session.c',
    119        autoproto='session_proto.h',
    12         public_deps='credentials',
     10        public_deps='samba-credentials',
    1311        public_headers='session.h',
    1412        header_path='samba',
     
    1614        )
    1715
     16bld.SAMBA_LIBRARY('auth_unix_token',
     17                  source='unix_token.c',
     18                  autoproto='unix_token_proto.h',
     19                  public_deps='LIBWBCLIENT_OLD',
     20                  private_library=True,
     21                  )
     22
    1823
    1924bld.SAMBA_SUBSYSTEM('samba_server_gensec',
    2025        source='samba_server_gensec.c',
    21         public_deps='credentials gensec auth4'
     26        public_deps='samba-credentials gensec auth4'
    2227        )
    2328
     
    2631        source='system_session.c',
    2732        autoproto='system_session_proto.h',
    28         public_deps='credentials',
     33        public_deps='samba-credentials',
    2934        deps='auth_session',
    3035        )
     
    3439        source='sam.c',
    3540        autoproto='auth_sam.h',
    36         public_deps='samdb security ldb tevent',
     41        public_deps='samdb samba-security ldb tevent',
    3742        deps=''
    3843        )
  • vendor/current/source4/auth/wscript_configure

    r740 r988  
    33conf.CHECK_HEADERS('security/pam_appl.h')
    44conf.CHECK_FUNCS_IN('pam_start', 'pam', checklibc=True)
    5 
    6 if (conf.CHECK_HEADERS('sasl/sasl.h') and
    7     conf.CHECK_FUNCS_IN('sasl_client_init', 'sasl2')):
    8     conf.DEFINE('HAVE_SASL', 1)
Note: See TracChangeset for help on using the changeset viewer.