Changeset 988 for vendor/current/source4/auth/gensec
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- Location:
- vendor/current/source4/auth/gensec
- Files:
-
- 2 added
- 8 deleted
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source4/auth/gensec/gensec_gssapi.c
r740 r988 25 25 #include "lib/events/events.h" 26 26 #include "system/kerberos.h" 27 #include "system/gssapi.h" 27 28 #include "auth/kerberos/kerberos.h" 28 29 #include "librpc/gen_ndr/krb5pac.h" … … 30 31 #include <ldb.h> 31 32 #include "auth/auth_sam.h" 32 #include "librpc/ rpc/dcerpc.h"33 #include "librpc/gen_ndr/dcerpc.h" 33 34 #include "auth/credentials/credentials.h" 34 35 #include "auth/credentials/credentials_krb5.h" 35 36 #include "auth/gensec/gensec.h" 37 #include "auth/gensec/gensec_internal.h" 36 38 #include "auth/gensec/gensec_proto.h" 39 #include "auth/gensec/gensec_toplevel_proto.h" 37 40 #include "param/param.h" 38 41 #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" 43 43 #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 48 gss_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); 44 54 45 55 static size_t gensec_gssapi_max_input_size(struct gensec_security *gensec_security); 46 56 static 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 57 static size_t gensec_gssapi_sig_size(struct gensec_security *gensec_security, size_t data_size); 85 58 86 59 static int gensec_gssapi_destructor(struct gensec_gssapi_state *gensec_gssapi_state) 87 60 { 88 OM_uint32 m aj_stat, min_stat;89 61 OM_uint32 min_stat; 62 90 63 if (gensec_gssapi_state->delegated_cred_handle != GSS_C_NO_CREDENTIAL) { 91 maj_stat = gss_release_cred(&min_stat,92 64 gss_release_cred(&min_stat, 65 &gensec_gssapi_state->delegated_cred_handle); 93 66 } 94 67 95 68 if (gensec_gssapi_state->gssapi_context != GSS_C_NO_CONTEXT) { 96 maj_stat = gss_delete_sec_context(&min_stat,97 98 69 gss_delete_sec_context(&min_stat, 70 &gensec_gssapi_state->gssapi_context, 71 GSS_C_NO_BUFFER); 99 72 } 100 73 101 74 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); 103 77 } 104 78 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); 110 81 } 111 82 112 83 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;144 84 } 145 85 … … 148 88 struct gensec_gssapi_state *gensec_gssapi_state; 149 89 krb5_error_code ret; 90 #ifdef SAMBA4_USES_HEIMDAL 150 91 const char *realm; 92 #endif 151 93 152 94 gensec_gssapi_state = talloc_zero(gensec_security, struct gensec_gssapi_state); … … 165 107 gensec_gssapi_state->client_name = GSS_C_NO_NAME; 166 108 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; 168 111 169 112 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; 171 114 } 172 115 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; 174 117 } 175 118 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; 177 120 } 178 121 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; 180 123 } 181 124 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; 183 126 } 184 127 185 128 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; 187 130 } 188 131 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; 190 134 } 191 135 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->g ot_flags = 0;136 gensec_gssapi_state->gss_want_flags |= GSS_C_DCE_STYLE; 137 } 138 139 gensec_gssapi_state->gss_got_flags = 0; 196 140 197 141 switch (gensec_security->ops->auth_type) { … … 201 145 case DCERPC_AUTH_TYPE_KRB5: 202 146 default: 203 gensec_gssapi_state->gss_oid = gss_mech_krb5; 147 gensec_gssapi_state->gss_oid = 148 discard_const_p(void, gss_mech_krb5); 204 149 break; 205 150 } 206 151 207 gensec_gssapi_state->session_key = data_blob(NULL, 0);208 gensec_gssapi_state->pac = data_blob(NULL, 0);209 210 152 ret = smb_krb5_init_context(gensec_gssapi_state, 211 NULL,212 153 gensec_security->settings->lp_ctx, 213 154 &gensec_gssapi_state->smb_krb5_context); 214 155 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", 216 157 error_message(ret))); 217 158 talloc_free(gensec_gssapi_state); … … 221 162 gensec_gssapi_state->client_cred = NULL; 222 163 gensec_gssapi_state->server_cred = NULL; 223 224 gensec_gssapi_state->lucid = NULL;225 164 226 165 gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL; … … 237 176 talloc_set_destructor(gensec_gssapi_state, gensec_gssapi_destructor); 238 177 178 #ifdef SAMBA4_USES_HEIMDAL 239 179 realm = lpcfg_realm(gensec_security->settings->lp_ctx); 240 180 if (realm != NULL) { 241 181 ret = gsskrb5_set_default_realm(realm); 242 182 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")); 244 184 talloc_free(gensec_gssapi_state); 245 185 return NT_STATUS_INTERNAL_ERROR; … … 250 190 ret = gsskrb5_set_dns_canonicalize(gensec_setting_bool(gensec_security->settings, "krb5", "set_dns_canonicalize", false)); 251 191 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")); 253 193 talloc_free(gensec_gssapi_state); 254 194 return NT_STATUS_INTERNAL_ERROR; 255 195 } 256 196 #endif 257 197 return NT_STATUS_OK; 258 198 } … … 306 246 } 307 247 308 static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_security) 248 static NTSTATUS gensec_gssapi_client_creds(struct gensec_security *gensec_security, 249 struct tevent_context *ev) 309 250 { 310 251 struct gensec_gssapi_state *gensec_gssapi_state; 252 struct gssapi_creds_container *gcc; 311 253 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;319 254 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; 338 256 339 257 gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); 340 258 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, 368 266 gensec_security->settings->lp_ctx, &gcc, &error_string); 369 267 switch (ret) { 370 268 case 0: 371 269 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; 372 273 case KRB5KDC_ERR_PREAUTH_FAILED: 373 274 case KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN: 275 case KRB5KRB_AP_ERR_BAD_INTEGRITY: 374 276 DEBUG(1, ("Wrong username or password: %s\n", error_string)); 375 277 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: 376 282 case KRB5_KDC_UNREACH: 377 283 DEBUG(3, ("Cannot reach a KDC we require to contact %s : %s\n", gensec_gssapi_state->target_principal, error_string)); … … 390 296 return NT_STATUS_NO_MEMORY; 391 297 } 392 298 299 return NT_STATUS_OK; 300 } 301 302 static 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 393 361 return NT_STATUS_OK; 394 362 } … … 405 373 } 406 374 return nt_status; 407 }408 409 410 /**411 * Check if the packet is one for this mechansim412 *413 * @param gensec_security GENSEC state414 * @param in The request, as a DATA_BLOB415 * @return Error, INVALID_PARAMETER if it's not a packet for us416 * 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 }427 375 } 428 376 … … 440 388 441 389 static 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) 444 393 { 445 394 struct gensec_gssapi_state *gensec_gssapi_state … … 448 397 OM_uint32 maj_stat, min_stat; 449 398 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 451 402 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 452 411 input_token.length = in.length; 453 412 input_token.value = in.data; … … 459 418 case GENSEC_CLIENT: 460 419 { 420 #ifdef SAMBA4_USES_HEIMDAL 461 421 struct gsskrb5_send_to_kdc send_to_kdc; 462 422 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 463 431 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; 465 433 466 434 min_stat = gsskrb5_set_send_to_kdc(&send_to_kdc); 467 435 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")); 469 437 return NT_STATUS_INTERNAL_ERROR; 470 438 } 471 439 #endif 472 440 maj_stat = gss_init_sec_context(&min_stat, 473 441 gensec_gssapi_state->client_cred->creds, … … 475 443 gensec_gssapi_state->server_name, 476 444 gensec_gssapi_state->gss_oid, 477 gensec_gssapi_state-> want_flags,478 0,445 gensec_gssapi_state->gss_want_flags, 446 time_req, 479 447 gensec_gssapi_state->input_chan_bindings, 480 448 &input_token, 481 449 &gss_oid_p, 482 450 &output_token, 483 &gensec_gssapi_state->g ot_flags, /* ret flags */484 NULL);451 &gensec_gssapi_state->gss_got_flags, /* ret flags */ 452 &time_rec); 485 453 if (gss_oid_p) { 486 454 gensec_gssapi_state->gss_oid = gss_oid_p; 487 455 } 488 456 457 #ifdef SAMBA4_USES_HEIMDAL 489 458 send_to_kdc.func = smb_krb5_send_and_recv_func; 490 459 send_to_kdc.ptr = NULL; … … 492 461 ret = gsskrb5_set_send_to_kdc(&send_to_kdc); 493 462 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")); 495 464 return NT_STATUS_INTERNAL_ERROR; 496 465 } 497 466 #endif 498 467 break; 499 468 } … … 508 477 &gss_oid_p, 509 478 &output_token, 510 &gensec_gssapi_state->g ot_flags,511 NULL,479 &gensec_gssapi_state->gss_got_flags, 480 &time_rec, 512 481 &gensec_gssapi_state->delegated_cred_handle); 513 482 if (gss_oid_p) { … … 527 496 gss_release_buffer(&min_stat2, &output_token); 528 497 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) { 530 500 DEBUG(5, ("gensec_gssapi: credentials were delegated\n")); 531 501 } else { 532 502 DEBUG(5, ("gensec_gssapi: NO credentials were delegated\n")); 533 503 } 504 505 tv = timeval_current_ofs(time_rec, 0); 506 gensec_gssapi_state->expire_time = timeval_to_nttime(&tv); 534 507 535 508 /* We may have been invoked as SASL, so there … … 556 529 557 530 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)) { 559 594 switch (min_stat) { 560 595 case KRB5KRB_AP_ERR_TKT_NYV: … … 569 604 return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */ 570 605 case KRB5_KDC_UNREACH: 571 DEBUG(3, ("Cannot reach a KDC we require in order to obtain a tic etkto %s: %s\n",606 DEBUG(3, ("Cannot reach a KDC we require in order to obtain a ticket to %s: %s\n", 572 607 gensec_gssapi_state->target_principal, 573 608 gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); … … 586 621 gensec_gssapi_state->gss_exchange_count, 587 622 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; 589 624 } 590 625 } else { … … 593 628 gensec_gssapi_state->gss_exchange_count, 594 629 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; 596 631 } 597 632 break; … … 942 977 if (GSS_ERROR(maj_stat)) { 943 978 TALLOC_CTX *mem_ctx = talloc_new(NULL); 944 DEBUG(1, ("gensec_gssapi_max_input_size: determin aing 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", 945 980 gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); 946 981 talloc_free(mem_ctx); … … 966 1001 struct gensec_gssapi_state *gensec_gssapi_state 967 1002 = 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 1009 1027 return NT_STATUS_OK; 1010 1028 } 1011 1029 1012 1030 static NTSTATUS gensec_gssapi_unseal_packet(struct gensec_security *gensec_security, 1013 TALLOC_CTX *mem_ctx,1014 1031 uint8_t *data, size_t length, 1015 1032 const uint8_t *whole_pdu, size_t pdu_length, … … 1018 1035 struct gensec_gssapi_state *gensec_gssapi_state 1019 1036 = 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 1060 1058 return NT_STATUS_OK; 1061 1059 } … … 1069 1067 struct gensec_gssapi_state *gensec_gssapi_state 1070 1068 = 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; 1073 1071 1074 1072 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 } 1098 1089 1099 1090 return NT_STATUS_OK; … … 1101 1092 1102 1093 static NTSTATUS gensec_gssapi_check_packet(struct gensec_security *gensec_security, 1103 TALLOC_CTX *mem_ctx,1104 1094 const uint8_t *data, size_t length, 1105 1095 const uint8_t *whole_pdu, size_t pdu_length, … … 1108 1098 struct gensec_gssapi_state *gensec_gssapi_state 1109 1099 = 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; 1116 1102 1117 1103 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; 1137 1119 } 1138 1120 … … 1151 1133 && gensec_gssapi_state->sasl_state == STAGE_DONE) { 1152 1134 return ((gensec_gssapi_state->sasl_protection & NEG_SIGN) 1153 && (gensec_gssapi_state->g ot_flags & GSS_C_INTEG_FLAG));1154 } 1155 return gensec_gssapi_state->g ot_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; 1156 1138 } 1157 1139 if (feature & GENSEC_FEATURE_SEAL) { … … 1160 1142 && gensec_gssapi_state->sasl_state == STAGE_DONE) { 1161 1143 return ((gensec_gssapi_state->sasl_protection & NEG_SEAL) 1162 && (gensec_gssapi_state->g ot_flags & GSS_C_CONF_FLAG));1163 } 1164 return gensec_gssapi_state->g ot_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; 1165 1147 } 1166 1148 if (feature & GENSEC_FEATURE_SESSION_KEY) { 1167 1149 /* 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)) { 1169 1152 return true; 1170 1153 } 1171 1154 } 1172 1155 if (feature & GENSEC_FEATURE_DCE_STYLE) { 1173 return gensec_gssapi_state->g ot_flags & GSS_C_DCE_STYLE;1156 return gensec_gssapi_state->gss_got_flags & GSS_C_DCE_STYLE; 1174 1157 } 1175 1158 if (feature & GENSEC_FEATURE_NEW_SPNEGO) { 1176 1159 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)) { 1179 1163 return false; 1180 1164 } … … 1187 1171 } 1188 1172 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; 1199 1194 } 1200 1195 /* We can always do async (rather than strict request/reply) packets. */ … … 1202 1197 return true; 1203 1198 } 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 } 1204 1210 return false; 1211 } 1212 1213 static 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; 1205 1220 } 1206 1221 … … 1212 1227 */ 1213 1228 static NTSTATUS gensec_gssapi_session_key(struct gensec_security *gensec_security, 1229 TALLOC_CTX *mem_ctx, 1214 1230 DATA_BLOB *session_key) 1215 1231 { 1216 1232 struct gensec_gssapi_state *gensec_gssapi_state 1217 1233 = 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); 1248 1235 } 1249 1236 … … 1252 1239 * database lookup */ 1253 1240 static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_security, 1241 TALLOC_CTX *mem_ctx, 1254 1242 struct auth_session_info **_session_info) 1255 1243 { 1256 1244 NTSTATUS nt_status; 1257 TALLOC_CTX * mem_ctx;1245 TALLOC_CTX *tmp_ctx; 1258 1246 struct gensec_gssapi_state *gensec_gssapi_state 1259 1247 = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); 1260 struct auth_user_info_dc *user_info_dc = NULL;1261 1248 struct auth_session_info *session_info = NULL; 1262 1249 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; 1267 1254 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); 1291 1283 1292 1284 /* IF we have the PAC - otherwise we need to get this … … 1294 1286 * kind... 1295 1287 */ 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); 1369 1297 if (!NT_STATUS_IS_OK(nt_status)) { 1370 talloc_free( mem_ctx);1298 talloc_free(tmp_ctx); 1371 1299 return nt_status; 1372 1300 } 1373 1301 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); 1375 1303 if (!NT_STATUS_IS_OK(nt_status)) { 1376 talloc_free( mem_ctx);1304 talloc_free(tmp_ctx); 1377 1305 return nt_status; 1378 1306 } 1379 1307 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) { 1389 1310 krb5_error_code ret; 1390 1311 const char *error_string; … … 1393 1314 session_info->credentials = cli_credentials_init(session_info); 1394 1315 if (!session_info->credentials) { 1395 talloc_free( mem_ctx);1316 talloc_free(tmp_ctx); 1396 1317 return NT_STATUS_NO_MEMORY; 1397 1318 } … … 1406 1327 CRED_SPECIFIED, &error_string); 1407 1328 if (ret) { 1408 talloc_free( mem_ctx);1329 talloc_free(tmp_ctx); 1409 1330 DEBUG(2,("Failed to get gss creds: %s\n", error_string)); 1410 1331 return NT_STATUS_NO_MEMORY; … … 1416 1337 /* It has been taken from this place... */ 1417 1338 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); 1422 1345 1423 1346 return NT_STATUS_OK; … … 1428 1351 struct gensec_gssapi_state *gensec_gssapi_state 1429 1352 = 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) { 1433 1356 return gensec_gssapi_state->sig_size; 1434 1357 } 1435 1358 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; 1478 1365 return gensec_gssapi_state->sig_size; 1479 1366 } … … 1498 1385 .client_start = gensec_gssapi_client_start, 1499 1386 .server_start = gensec_gssapi_server_start, 1500 .magic = gensec_ gssapi_magic,1387 .magic = gensec_magic_check_krb5_oid, 1501 1388 .update = gensec_gssapi_update, 1502 1389 .session_key = gensec_gssapi_session_key, … … 1506 1393 .seal_packet = gensec_gssapi_seal_packet, 1507 1394 .unseal_packet = gensec_gssapi_unseal_packet, 1395 .max_input_size = gensec_gssapi_max_input_size, 1396 .max_wrapped_size = gensec_gssapi_max_wrapped_size, 1508 1397 .wrap = gensec_gssapi_wrap, 1509 1398 .unwrap = gensec_gssapi_unwrap, 1510 1399 .have_feature = gensec_gssapi_have_feature, 1400 .expire_time = gensec_gssapi_expire_time, 1511 1401 .enabled = false, 1512 1402 .kerberos = true, … … 1521 1411 .client_start = gensec_gssapi_client_start, 1522 1412 .server_start = gensec_gssapi_server_start, 1523 .magic = gensec_ gssapi_magic,1413 .magic = gensec_magic_check_krb5_oid, 1524 1414 .update = gensec_gssapi_update, 1525 1415 .session_key = gensec_gssapi_session_key, … … 1530 1420 .seal_packet = gensec_gssapi_seal_packet, 1531 1421 .unseal_packet = gensec_gssapi_unseal_packet, 1422 .max_input_size = gensec_gssapi_max_input_size, 1423 .max_wrapped_size = gensec_gssapi_max_wrapped_size, 1532 1424 .wrap = gensec_gssapi_wrap, 1533 1425 .unwrap = gensec_gssapi_unwrap, 1534 1426 .have_feature = gensec_gssapi_have_feature, 1427 .expire_time = gensec_gssapi_expire_time, 1535 1428 .enabled = true, 1536 1429 .kerberos = true, … … 1552 1445 .unwrap = gensec_gssapi_unwrap, 1553 1446 .have_feature = gensec_gssapi_have_feature, 1447 .expire_time = gensec_gssapi_expire_time, 1554 1448 .enabled = true, 1555 1449 .kerberos = true, -
vendor/current/source4/auth/gensec/gensec_gssapi.h
r740 r988 1 /* 1 /* 2 2 Unix SMB/CIFS implementation. 3 3 4 4 Kerberos backend for GENSEC 5 5 6 6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005 7 7 Copyright (C) Stefan Metzmacher <metze@samba.org> 2004-2005 … … 11 11 the Free Software Foundation; either version 3 of the License, or 12 12 (at your option) any later version. 13 13 14 14 This program is distributed in the hope that it will be useful, 15 15 but WITHOUT ANY WARRANTY; without even the implied warranty of … … 17 17 GNU General Public License for more details. 18 18 19 19 20 20 You should have received a copy of the GNU General Public License 21 21 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 24 24 /* This structure described here, so the RPC-PAC test can get at the PAC provided */ 25 25 26 enum gensec_gssapi_sasl_state 26 enum gensec_gssapi_sasl_state 27 27 { 28 28 STAGE_GSS_NEG, … … 38 38 struct gensec_gssapi_state { 39 39 gss_ctx_id_t gssapi_context; 40 struct gss_channel_bindings_struct *input_chan_bindings;41 40 gss_name_t server_name; 42 41 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 */ 44 49 gss_OID gss_oid; 45 50 46 DATA_BLOB session_key; 47 DATA_BLOB pac; 48 51 struct gss_channel_bindings_struct *input_chan_bindings; 49 52 struct smb_krb5_context *smb_krb5_context; 50 53 struct gssapi_creds_container *client_cred; 51 54 struct gssapi_creds_container *server_cred; 52 gss_krb5_lucid_context_v1_t *lucid;53 54 gss_cred_id_t delegated_cred_handle;55 55 56 56 bool sasl; /* We have two different mechs in this file: One … … 68 68 const char *target_principal; 69 69 }; 70 -
vendor/current/source4/auth/gensec/gensec_krb5.c
r740 r988 28 28 #include "auth/kerberos/kerberos.h" 29 29 #include "auth/auth.h" 30 #include "lib/socket/socket.h"31 30 #include "lib/tsocket/tsocket.h" 32 #include "librpc/ rpc/dcerpc.h"31 #include "librpc/gen_ndr/dcerpc.h" 33 32 #include "auth/credentials/credentials.h" 34 33 #include "auth/credentials/credentials_krb5.h" 35 34 #include "auth/kerberos/kerberos_credentials.h" 36 35 #include "auth/gensec/gensec.h" 36 #include "auth/gensec/gensec_internal.h" 37 37 #include "auth/gensec/gensec_proto.h" 38 #include "auth/gensec/gensec_toplevel_proto.h" 38 39 #include "param/param.h" 39 40 #include "auth/auth_sam_reply.h" 40 41 #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); 41 47 42 48 enum GENSEC_KRB5_STATE { … … 48 54 49 55 struct gensec_krb5_state { 50 DATA_BLOB session_key;51 DATA_BLOB pac;52 56 enum GENSEC_KRB5_STATE state_position; 53 57 struct smb_krb5_context *smb_krb5_context; … … 113 117 ZERO_STRUCT(gensec_krb5_state->enc_ticket); 114 118 gensec_krb5_state->keyblock = NULL; 115 gensec_krb5_state->session_key = data_blob(NULL, 0);116 gensec_krb5_state->pac = data_blob(NULL, 0);117 119 gensec_krb5_state->gssapi = gssapi; 118 120 … … 234 236 static NTSTATUS gensec_krb5_common_client_start(struct gensec_security *gensec_security, bool gssapi) 235 237 { 238 const char *hostname; 236 239 struct gensec_krb5_state *gensec_krb5_state; 237 krb5_error_code ret;238 240 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 246 241 hostname = gensec_get_target_hostname(gensec_security); 247 242 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")); 249 244 return NT_STATUS_INVALID_PARAMETER; 250 245 } … … 268 263 269 264 if (gensec_krb5_state->gssapi) { 270 /* The Fake GSSAPI mod al emulates Samba3, which does not do mutual authentication */265 /* The Fake GSSAPI model emulates Samba3, which does not do mutual authentication */ 271 266 if (gensec_setting_bool(gensec_security->settings, "gensec_fake_gssapi_krb5", "mutual", false)) { 272 267 gensec_krb5_state->ap_req_options |= AP_OPTS_MUTUAL_REQUIRED; … … 278 273 } 279 274 } 275 return NT_STATUS_OK; 276 } 277 278 static 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; 280 298 281 299 principal = gensec_get_target_principal(gensec_security); 300 hostname = gensec_get_target_hostname(gensec_security); 282 301 283 302 ret = cli_credentials_get_ccache(gensec_get_credentials(gensec_security), 284 gensec_security->event_ctx,303 ev, 285 304 gensec_security->settings->lp_ctx, &ccache_container, &error_string); 286 305 switch (ret) { … … 301 320 return NT_STATUS_UNSUCCESSFUL; 302 321 } 303 in_data.length = 0;304 322 305 323 /* 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); 307 325 if (ret != 0) { 308 326 DEBUG(1, ("gensec_krb5_start: Setting event context failed\n")); … … 318 336 gensec_krb5_state->ap_req_options, 319 337 target_principal, 320 &in_data, ccache_container->ccache,338 in_data_p, ccache_container->ccache, 321 339 &gensec_krb5_state->enc_ticket); 322 340 krb5_free_principal(gensec_krb5_state->smb_krb5_context->krb5_context, … … 329 347 gensec_get_target_service(gensec_security), 330 348 hostname, 331 &in_data, ccache_container->ccache,349 in_data_p, ccache_container->ccache, 332 350 &gensec_krb5_state->enc_ticket); 333 351 } 334 352 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); 336 354 337 355 switch (ret) { … … 383 401 } 384 402 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 */ 407 static 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 */ 443 static 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); 399 461 } 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 } 404 478 405 479 /** … … 416 490 static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, 417 491 TALLOC_CTX *out_mem_ctx, 492 struct tevent_context *ev, 418 493 const DATA_BLOB in, DATA_BLOB *out) 419 494 { … … 427 502 DATA_BLOB unwrapped_out; 428 503 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 429 509 if (gensec_krb5_state->gssapi) { 430 510 unwrapped_out = data_blob_talloc(out_mem_ctx, gensec_krb5_state->enc_ticket.data, gensec_krb5_state->enc_ticket.length); … … 506 586 } 507 587 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 */ 509 592 ret = principal_from_credentials(out_mem_ctx, gensec_get_credentials(gensec_security), 510 593 gensec_krb5_state->smb_krb5_context, … … 514 597 DEBUG(2,("Failed to make credentials from principal: %s\n", error_string)); 515 598 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; 516 609 } 517 610 … … 557 650 558 651 static NTSTATUS gensec_krb5_session_key(struct gensec_security *gensec_security, 652 TALLOC_CTX *mem_ctx, 559 653 DATA_BLOB *session_key) 560 654 { … … 567 661 if (gensec_krb5_state->state_position != GENSEC_KRB5_DONE) { 568 662 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;574 663 } 575 664 … … 585 674 DEBUG(10, ("Got KRB5 session key of length %d\n", 586 675 (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)); 590 678 dump_data_pw("KRB5 Session Key:\n", session_key->data, session_key->length); 591 679 … … 599 687 600 688 static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security, 689 TALLOC_CTX *mem_ctx, 601 690 struct auth_session_info **_session_info) 602 691 { … … 604 693 struct gensec_krb5_state *gensec_krb5_state = (struct gensec_krb5_state *)gensec_security->private_data; 605 694 krb5_context context = gensec_krb5_state->smb_krb5_context->krb5_context; 606 struct auth_user_info_dc *user_info_dc = NULL;607 695 struct auth_session_info *session_info = NULL; 608 struct PAC_LOGON_INFO *logon_info;609 696 610 697 krb5_principal client_principal; 611 698 char *principal_string; 612 699 613 DATA_BLOB pac ;700 DATA_BLOB pac_blob, *pac_blob_ptr = NULL; 614 701 krb5_data pac_data; 615 702 616 703 krb5_error_code ret; 617 704 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) { 620 707 return NT_STATUS_NO_MEMORY; 621 708 } … … 625 712 DEBUG(5, ("krb5_ticket_get_client failed to get cleint principal: %s\n", 626 713 smb_get_krb5_error_message(context, 627 ret, mem_ctx)));628 talloc_free( mem_ctx);714 ret, tmp_ctx))); 715 talloc_free(tmp_ctx); 629 716 return NT_STATUS_NO_MEMORY; 630 717 } … … 635 722 DEBUG(1, ("Unable to parse client principal: %s\n", 636 723 smb_get_krb5_error_message(context, 637 ret, mem_ctx)));724 ret, tmp_ctx))); 638 725 krb5_free_principal(context, client_principal); 639 talloc_free( mem_ctx);726 talloc_free(tmp_ctx); 640 727 return NT_STATUS_NO_MEMORY; 641 728 } … … 645 732 &pac_data); 646 733 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) { 657 735 /* NO pac */ 658 736 DEBUG(5, ("krb5_ticket_get_authorization_data_type failed to find PAC: %s\n", 659 737 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) { 679 744 free(principal_string); 680 745 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); 693 747 return NT_STATUS_NO_MEMORY; 694 748 } 695 749 696 750 /* decode and verify the pac */ 697 nt_status = kerberos_ pac_logon_info(gensec_krb5_state,698 &logon_info, pac,699 700 701 702 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); 703 757 704 758 if (!NT_STATUS_IS_OK(nt_status)) { 705 759 free(principal_string); 706 760 krb5_free_principal(context, client_principal); 707 talloc_free( mem_ctx);761 talloc_free(tmp_ctx); 708 762 return nt_status; 709 763 } 710 764 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); 723 774 724 775 free(principal_string); 725 776 krb5_free_principal(context, client_principal); 726 777 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 730 778 if (!NT_STATUS_IS_OK(nt_status)) { 731 talloc_free( mem_ctx);779 talloc_free(tmp_ctx); 732 780 return nt_status; 733 781 } 734 782 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); 736 784 737 785 if (!NT_STATUS_IS_OK(nt_status)) { 738 talloc_free( mem_ctx);786 talloc_free(tmp_ctx); 739 787 return nt_status; 740 788 } 741 789 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); 746 793 return NT_STATUS_OK; 747 794 } … … 836 883 .server_start = gensec_fake_gssapi_krb5_server_start, 837 884 .update = gensec_krb5_update, 838 .magic = gensec_ fake_gssapi_krb5_magic,885 .magic = gensec_magic_check_krb5_oid, 839 886 .session_key = gensec_krb5_session_key, 840 887 .session_info = gensec_krb5_session_info, … … 874 921 if (!NT_STATUS_IS_OK(ret)) { 875 922 DEBUG(0,("Failed to register '%s' gensec backend!\n", 876 gensec_ krb5_security_ops.name));923 gensec_fake_gssapi_krb5_security_ops.name)); 877 924 return ret; 878 925 } -
vendor/current/source4/auth/gensec/gensec_tstream.c
r740 r988 28 28 #include "lib/tsocket/tsocket.h" 29 29 #include "lib/tsocket/tsocket_internal.h" 30 30 #include "auth/gensec/gensec_toplevel_proto.h" 31 31 32 32 static const struct tstream_context_ops tstream_gensec_ops; … … 248 248 vector[0].iov_len = sizeof(state->wrapped.hdr); 249 249 } else if (!state->wrapped.asked_for_blob) { 250 uint32_t msg_len; 251 250 252 state->wrapped.asked_for_blob = true; 251 uint32_t msg_len;252 253 253 254 msg_len = RIVAL(state->wrapped.hdr, 0); 254 255 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) { 256 261 errno = EMSGSIZE; 257 262 return -1; -
vendor/current/source4/auth/gensec/pygensec.c
r740 r988 21 21 #include "param/pyparam.h" 22 22 #include "auth/gensec/gensec.h" 23 #include "auth/gensec/gensec_internal.h" /* TODO: remove this */ 23 24 #include "auth/credentials/pycredentials.h" 24 25 #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> 27 28 #include <tevent.h> 28 29 #include "librpc/rpc/pyrpc_util.h" … … 37 38 return NULL; 38 39 39 security = py _talloc_get_type(self, struct gensec_security);40 security = pytalloc_get_type(self, struct gensec_security); 40 41 41 42 name = gensec_get_name_by_authtype(security, type); … … 79 80 { 80 81 NTSTATUS status; 81 py_talloc_Object *self;82 PyObject *self; 82 83 struct gensec_settings *settings; 83 84 const char *kwnames[] = { "settings", NULL }; 84 PyObject *py_settings; 85 struct tevent_context *ev; 85 PyObject *py_settings = Py_None; 86 86 struct gensec_security *gensec; 87 TALLOC_CTX *frame; 87 88 88 89 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", discard_const_p(char *, kwnames), &py_settings)) 89 90 return NULL; 90 91 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(); 101 93 102 94 if (py_settings != Py_None) { 103 settings = settings_from_object( self->talloc_ctx, py_settings);95 settings = settings_from_object(frame, py_settings); 104 96 if (settings == NULL) { 105 PyObject_DEL(self); 97 PyErr_NoMemory(); 98 TALLOC_FREE(frame); 106 99 return NULL; 107 100 } 108 101 } else { 109 settings = talloc_zero( self->talloc_ctx, struct gensec_settings);102 settings = talloc_zero(frame, struct gensec_settings); 110 103 if (settings == NULL) { 111 PyObject_DEL(self); 104 PyErr_NoMemory(); 105 TALLOC_FREE(frame); 112 106 return NULL; 113 107 } 114 108 115 109 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); 140 133 141 134 return (PyObject *)self; … … 145 138 { 146 139 NTSTATUS status; 147 py_talloc_Object *self;140 PyObject *self; 148 141 struct gensec_settings *settings = NULL; 149 142 const char *kwnames[] = { "settings", "auth_context", NULL }; 150 143 PyObject *py_settings = Py_None; 151 144 PyObject *py_auth_context = Py_None; 152 struct tevent_context *ev;153 145 struct gensec_security *gensec; 154 struct auth_context *auth_context = NULL; 146 struct auth4_context *auth_context = NULL; 147 TALLOC_CTX *frame; 155 148 156 149 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OO", discard_const_p(char *, kwnames), &py_settings, &py_auth_context)) 157 150 return NULL; 158 151 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(); 169 153 170 154 if (py_settings != Py_None) { 171 settings = settings_from_object( self->talloc_ctx, py_settings);155 settings = settings_from_object(frame, py_settings); 172 156 if (settings == NULL) { 173 PyObject_DEL(self); 157 PyErr_NoMemory(); 158 TALLOC_FREE(frame); 174 159 return NULL; 175 160 } 176 161 } else { 177 settings = talloc_zero( self->talloc_ctx, struct gensec_settings);162 settings = talloc_zero(frame, struct gensec_settings); 178 163 if (settings == NULL) { 179 PyObject_DEL(self); 164 PyErr_NoMemory(); 165 TALLOC_FREE(frame); 180 166 return NULL; 181 167 } 182 168 183 169 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 } 191 175 } 192 176 193 177 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); 195 179 if (!auth_context) { 196 180 PyErr_Format(PyExc_TypeError, 197 181 "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))); 199 183 return NULL; 200 184 } 201 185 } 202 186 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 207 static 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 225 static 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; 220 241 } 221 242 … … 224 245 PyObject *py_creds = Py_None; 225 246 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); 227 248 NTSTATUS status; 228 249 … … 234 255 PyErr_Format(PyExc_TypeError, 235 256 "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))); 237 258 } 238 259 … … 248 269 static PyObject *py_gensec_session_info(PyObject *self) 249 270 { 271 TALLOC_CTX *mem_ctx; 250 272 NTSTATUS status; 251 273 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); 253 275 struct auth_session_info *info; 254 276 if (security->ops == NULL) { … … 256 278 return NULL; 257 279 } 258 status = gensec_session_info(security, &info); 280 mem_ctx = talloc_new(NULL); 281 282 status = gensec_session_info(security, mem_ctx, &info); 259 283 if (NT_STATUS_IS_ERR(status)) { 260 284 PyErr_SetNTSTATUS(status); … … 262 286 } 263 287 264 py_session_info = py_return_ndr_struct("samba. auth", "AuthSession",288 py_session_info = py_return_ndr_struct("samba.dcerpc.auth", "session_info", 265 289 info, info); 290 talloc_free(mem_ctx); 266 291 return py_session_info; 267 292 } 268 293 294 static 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 269 321 static PyObject *py_gensec_start_mech_by_name(PyObject *self, PyObject *args) 270 322 { 271 323 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); 273 325 NTSTATUS status; 274 326 … … 288 340 { 289 341 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); 291 343 NTSTATUS status; 292 344 … … 306 358 { 307 359 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); 309 361 NTSTATUS status; 310 362 if (!PyArg_ParseTuple(args, "ii", &authtype, &level)) … … 323 375 { 324 376 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); 326 378 /* This is i (and declared as an int above) by design, as they are handled as an integer in python */ 327 379 if (!PyArg_ParseTuple(args, "i", &feature)) … … 336 388 { 337 389 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); 339 391 /* This is i (and declared as an int above) by design, as they are handled as an integer in python */ 340 392 if (!PyArg_ParseTuple(args, "i", &feature)) … … 347 399 } 348 400 401 static 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 414 static 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 349 422 static PyObject *py_gensec_update(PyObject *self, PyObject *args) 350 423 { … … 353 426 DATA_BLOB in, out; 354 427 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); 356 429 PyObject *finished_processing; 357 430 … … 396 469 DATA_BLOB in, out; 397 470 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); 399 472 400 473 if (!PyArg_ParseTuple(args, "O", &py_in)) … … 430 503 DATA_BLOB in, out; 431 504 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); 433 506 434 507 if (!PyArg_ParseTuple(args, "O", &py_in)) … … 456 529 talloc_free(mem_ctx); 457 530 return ret; 531 } 532 533 static 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 548 static 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 580 static 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; 458 608 } 459 609 … … 465 615 { "set_credentials", (PyCFunction)py_gensec_set_credentials, METH_VARARGS, 466 616 "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)" }, 467 621 { "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" }, 469 625 { "start_mech_by_name", (PyCFunction)py_gensec_start_mech_by_name, METH_VARARGS, 470 626 "S.start_mech_by_name(name)" }, 471 627 { "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)" }, 474 631 { "get_name_by_authtype", (PyCFunction)py_get_name_by_authtype, METH_VARARGS, 475 632 "S.get_name_by_authtype(authtype) -> name\nLookup an auth type." }, 476 633 { "want_feature", (PyCFunction)py_gensec_want_feature, METH_VARARGS, 477 634 "S.want_feature(feature)\n Request that GENSEC negotiate a particular feature." }, 478 635 { "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." }, 480 641 { "update", (PyCFunction)py_gensec_update, METH_VARARGS, 481 642 "S.update(blob_in) -> (finished, blob_out)\nPerform one step in a GENSEC dance. Repeat with new packets until finished is true or exception." }, … … 484 645 { "unwrap", (PyCFunction)py_gensec_unwrap, METH_VARARGS, 485 646 "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." }, 487 653 { NULL } 488 654 }; 489 655 490 656 static PyTypeObject Py_Security = { 491 .tp_name = " Security",657 .tp_name = "gensec.Security", 492 658 .tp_flags = Py_TPFLAGS_DEFAULT, 493 659 .tp_methods = py_gensec_security_methods, 494 .tp_basicsize = sizeof(py_talloc_Object),495 660 }; 496 661 … … 500 665 PyObject *m; 501 666 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) 507 668 return; 508 669 -
vendor/current/source4/auth/gensec/wscript_build
r740 r988 1 1 #!/usr/bin/env python 2 2 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 ) 3 bld.SAMBA_SUBSYSTEM('gensec_util', 4 source='gensec_tstream.c', 5 deps='tevent-util tevent samba-util LIBTSOCKET', 6 autoproto='gensec_proto.h') 12 7 13 8 bld.SAMBA_MODULE('gensec_krb5', 14 source='gensec_krb5.c ',9 source='gensec_krb5.c gensec_krb5_util.c', 15 10 subsystem='gensec', 16 11 init_function='gensec_krb5_init', 17 deps=' credentials authkrb5 auth_session com_err',12 deps='samba-credentials authkrb5 com_err gensec_util', 18 13 internal_module=False, 14 enabled=bld.AD_DC_BUILD_IS_ENABLED() and bld.CONFIG_SET('SAMBA4_USES_HEIMDAL') 19 15 ) 20 16 … … 24 20 subsystem='gensec', 25 21 init_function='gensec_gssapi_init', 26 deps='gssapi credentials authkrb5 com_err'22 deps='gssapi samba-credentials authkrb5 com_err gensec_util' 27 23 ) 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 57 24 58 25 bld.SAMBA_PYTHON('pygensec',
Note:
See TracChangeset
for help on using the changeset viewer.