Changeset 988 for vendor/current/source3/librpc
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- Location:
- vendor/current/source3/librpc
- Files:
-
- 3 added
- 635 deleted
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/librpc/crypto/gse.c
r746 r988 3 3 * RPC Pipe client and server routines 4 4 * Copyright (C) Simo Sorce 2010. 5 * Copyright (C) Andrew Bartlett 2004-2011. 6 * Copyright (C) Stefan Metzmacher <metze@samba.org> 2004-2005 5 7 * 6 8 * This program is free software; you can redistribute it and/or modify … … 22 24 #include "includes.h" 23 25 #include "gse.h" 24 25 #if defined(HAVE_KRB5) \ 26 && defined(HAVE_GSSAPI_GSSAPI_EXT_H) \ 27 && defined(HAVE_GSS_WRAP_IOV) \ 28 && defined(HAVE_GSS_GET_NAME_ATTRIBUTE) 29 30 #include "smb_krb5.h" 26 #include "libads/kerberos_proto.h" 27 #include "auth/common_auth.h" 28 #include "auth/gensec/gensec.h" 29 #include "auth/gensec/gensec_internal.h" 30 #include "auth/credentials/credentials.h" 31 #include "../librpc/gen_ndr/dcerpc.h" 32 33 #if defined(HAVE_KRB5) 34 35 #include "auth/kerberos/pac_utils.h" 36 #include "auth/kerberos/gssapi_helper.h" 31 37 #include "gse_krb5.h" 32 38 33 #include <gssapi/gssapi.h>34 #include <gssapi/gssapi_krb5.h>35 #include <gssapi/gssapi_ext.h>36 37 #ifndef GSS_KRB5_INQ_SSPI_SESSION_KEY_OID38 #define GSS_KRB5_INQ_SSPI_SESSION_KEY_OID_LENGTH 1139 #define GSS_KRB5_INQ_SSPI_SESSION_KEY_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x05"40 #endif41 42 gss_OID_desc gse_sesskey_inq_oid = {43 GSS_KRB5_INQ_SSPI_SESSION_KEY_OID_LENGTH,44 (void *)GSS_KRB5_INQ_SSPI_SESSION_KEY_OID45 };46 47 #ifndef GSS_KRB5_SESSION_KEY_ENCTYPE_OID48 #define GSS_KRB5_SESSION_KEY_ENCTYPE_OID_LENGTH 1049 #define GSS_KRB5_SESSION_KEY_ENCTYPE_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x04"50 #endif51 52 gss_OID_desc gse_sesskeytype_oid = {53 GSS_KRB5_SESSION_KEY_ENCTYPE_OID_LENGTH,54 (void *)GSS_KRB5_SESSION_KEY_ENCTYPE_OID55 };56 57 #define GSE_EXTRACT_RELEVANT_AUTHZ_DATA_OID_LENGTH 1258 /* EXTRACTION OID AUTHZ ID */59 #define GSE_EXTRACT_RELEVANT_AUTHZ_DATA_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x0a" "\x01"60 61 gss_OID_desc gse_authz_data_oid = {62 GSE_EXTRACT_RELEVANT_AUTHZ_DATA_OID_LENGTH,63 (void *)GSE_EXTRACT_RELEVANT_AUTHZ_DATA_OID64 };65 66 #ifndef GSS_KRB5_EXTRACT_AUTHTIME_FROM_SEC_CONTEXT_OID67 #define GSS_KRB5_EXTRACT_AUTHTIME_FROM_SEC_CONTEXT_OID_LENGTH 1168 #define GSS_KRB5_EXTRACT_AUTHTIME_FROM_SEC_CONTEXT_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x0c"69 #endif70 71 gss_OID_desc gse_authtime_oid = {72 GSS_KRB5_EXTRACT_AUTHTIME_FROM_SEC_CONTEXT_OID_LENGTH,73 (void *)GSS_KRB5_EXTRACT_AUTHTIME_FROM_SEC_CONTEXT_OID74 };75 76 39 static char *gse_errstr(TALLOC_CTX *mem_ctx, OM_uint32 maj, OM_uint32 min); 40 static size_t gensec_gse_sig_size(struct gensec_security *gensec_security, 41 size_t data_size); 77 42 78 43 struct gse_context { 44 gss_ctx_id_t gssapi_context; 45 gss_name_t server_name; 46 gss_name_t client_name; 47 OM_uint32 gss_want_flags, gss_got_flags; 48 size_t max_wrap_buf_size; 49 size_t sig_size; 50 51 gss_cred_id_t delegated_cred_handle; 52 53 NTTIME expire_time; 54 55 /* gensec_gse only */ 79 56 krb5_context k5ctx; 80 57 krb5_ccache ccache; 81 58 krb5_keytab keytab; 82 59 83 gss_ctx_id_t gss_ctx;84 85 60 gss_OID_desc gss_mech; 86 OM_uint32 gss_c_flags;87 61 gss_cred_id_t creds; 88 gss_name_t server_name;89 62 90 63 gss_OID ret_mech; 91 OM_uint32 ret_flags;92 gss_cred_id_t delegated_creds;93 gss_name_t client_name;94 95 bool more_processing;96 bool authenticated;97 64 }; 98 65 … … 101 68 { 102 69 struct gse_context *gse_ctx; 103 OM_uint32 gss_min , gss_maj;70 OM_uint32 gss_min; 104 71 105 72 gse_ctx = talloc_get_type_abort(ptr, struct gse_context); … … 116 83 gse_ctx->k5ctx = NULL; 117 84 } 118 if (gse_ctx->gss _ctx!= GSS_C_NO_CONTEXT) {119 gss_maj =gss_delete_sec_context(&gss_min,120 &gse_ctx->gss _ctx,85 if (gse_ctx->gssapi_context != GSS_C_NO_CONTEXT) { 86 (void)gss_delete_sec_context(&gss_min, 87 &gse_ctx->gssapi_context, 121 88 GSS_C_NO_BUFFER); 122 89 } 123 90 if (gse_ctx->server_name) { 124 gss_maj =gss_release_name(&gss_min,91 (void)gss_release_name(&gss_min, 125 92 &gse_ctx->server_name); 126 93 } 127 94 if (gse_ctx->client_name) { 128 gss_maj =gss_release_name(&gss_min,95 (void)gss_release_name(&gss_min, 129 96 &gse_ctx->client_name); 130 97 } 131 98 if (gse_ctx->creds) { 132 gss_maj =gss_release_cred(&gss_min,99 (void)gss_release_cred(&gss_min, 133 100 &gse_ctx->creds); 134 101 } 135 if (gse_ctx->delegated_creds) { 136 gss_maj = gss_release_cred(&gss_min, 137 &gse_ctx->delegated_creds); 138 } 139 if (gse_ctx->ret_mech) { 140 gss_maj = gss_release_oid(&gss_min, 141 &gse_ctx->ret_mech); 142 } 102 if (gse_ctx->delegated_cred_handle) { 103 (void)gss_release_cred(&gss_min, 104 &gse_ctx->delegated_cred_handle); 105 } 106 107 /* MIT and Heimdal differ as to if you can call 108 * gss_release_oid() on this OID, generated by 109 * gss_{accept,init}_sec_context(). However, as long as the 110 * oid is gss_mech_krb5 (which it always is at the moment), 111 * then this is a moot point, as both declare this particular 112 * OID static, and so no memory is lost. This assert is in 113 * place to ensure that the programmer who wishes to extend 114 * this code to EAP or other GSS mechanisms determines an 115 * implementation-dependent way of releasing any dynamically 116 * allocated OID */ 117 SMB_ASSERT(smb_gss_oid_equal(&gse_ctx->gss_mech, GSS_C_NO_OID) || 118 smb_gss_oid_equal(&gse_ctx->gss_mech, gss_mech_krb5)); 119 143 120 return 0; 144 121 } … … 160 137 talloc_set_destructor((TALLOC_CTX *)gse_ctx, gse_context_destructor); 161 138 139 gse_ctx->expire_time = GENSEC_EXPIRE_TIME_INFINITY; 140 gse_ctx->max_wrap_buf_size = UINT16_MAX; 141 162 142 memcpy(&gse_ctx->gss_mech, gss_mech_krb5, sizeof(gss_OID_desc)); 163 143 164 gse_ctx->gss_ c_flags = GSS_C_MUTUAL_FLAG |144 gse_ctx->gss_want_flags = GSS_C_MUTUAL_FLAG | 165 145 GSS_C_DELEG_FLAG | 166 146 GSS_C_DELEG_POLICY_FLAG | … … 168 148 GSS_C_SEQUENCE_FLAG; 169 149 if (do_sign) { 170 gse_ctx->gss_ c_flags |= GSS_C_INTEG_FLAG;150 gse_ctx->gss_want_flags |= GSS_C_INTEG_FLAG; 171 151 } 172 152 if (do_seal) { 173 gse_ctx->gss_c_flags |= GSS_C_CONF_FLAG; 174 } 175 176 gse_ctx->gss_c_flags |= add_gss_c_flags; 153 gse_ctx->gss_want_flags |= GSS_C_INTEG_FLAG; 154 gse_ctx->gss_want_flags |= GSS_C_CONF_FLAG; 155 } 156 157 gse_ctx->gss_want_flags |= add_gss_c_flags; 177 158 178 159 /* Initialize Kerberos Context */ … … 211 192 } 212 193 213 NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx,214 215 216 217 218 219 220 221 194 static NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx, 195 bool do_sign, bool do_seal, 196 const char *ccache_name, 197 const char *server, 198 const char *service, 199 const char *username, 200 const char *password, 201 uint32_t add_gss_c_flags, 202 struct gse_context **_gse_ctx) 222 203 { 223 204 struct gse_context *gse_ctx; 224 205 OM_uint32 gss_maj, gss_min; 225 gss_buffer_desc name_buffer = {0, NULL};206 gss_buffer_desc name_buffer = GSS_C_EMPTY_BUFFER; 226 207 gss_OID_set_desc mech_set; 208 #ifdef HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X 209 gss_buffer_desc empty_buffer = GSS_C_EMPTY_BUFFER; 210 #endif 227 211 NTSTATUS status; 228 212 … … 238 222 } 239 223 240 name_buffer.value = talloc_asprintf(gse_ctx, 241 "%s@%s", service, server); 224 /* Guess the realm based on the supplied service, and avoid the GSS libs 225 doing DNS lookups which may fail. 226 227 TODO: Loop with the KDC on some more combinations (local 228 realm in particular), possibly falling back to 229 GSS_C_NT_HOSTBASED_SERVICE 230 */ 231 name_buffer.value = kerberos_get_principal_from_service_hostname( 232 gse_ctx, service, server, lp_realm()); 242 233 if (!name_buffer.value) { 243 234 status = NT_STATUS_NO_MEMORY; … … 246 237 name_buffer.length = strlen((char *)name_buffer.value); 247 238 gss_maj = gss_import_name(&gss_min, &name_buffer, 248 GSS_C_NT_ HOSTBASED_SERVICE,239 GSS_C_NT_USER_NAME, 249 240 &gse_ctx->server_name); 250 241 if (gss_maj) { 251 DEBUG( 0, ("gss_import_name failed for %s, with [%s]\n",242 DEBUG(5, ("gss_import_name failed for %s, with [%s]\n", 252 243 (char *)name_buffer.value, 253 244 gse_errstr(gse_ctx, gss_maj, gss_min))); … … 270 261 NULL, NULL); 271 262 if (gss_maj) { 272 DEBUG( 0, ("gss_acquire_creds failed for %s, with [%s]\n",273 (char *)name_buffer.value,263 DEBUG(5, ("gss_acquire_creds failed for GSS_C_NO_NAME with [%s] -" 264 "the caller may retry after a kinit.\n", 274 265 gse_errstr(gse_ctx, gss_maj, gss_min))); 275 266 status = NT_STATUS_INTERNAL_ERROR; 276 267 goto err_out; 277 268 } 269 270 #ifdef HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X 271 /* 272 * Don't force GSS_C_CONF_FLAG and GSS_C_INTEG_FLAG. 273 * 274 * This allows us to disable SIGN and SEAL for 275 * AUTH_LEVEL_CONNECT and AUTH_LEVEL_INTEGRITY. 276 * 277 * https://groups.yahoo.com/neo/groups/cat-ietf/conversations/topics/575 278 * http://krbdev.mit.edu/rt/Ticket/Display.html?id=6938 279 */ 280 gss_maj = gss_set_cred_option(&gss_min, &gse_ctx->creds, 281 GSS_KRB5_CRED_NO_CI_FLAGS_X, 282 &empty_buffer); 283 if (gss_maj) { 284 DEBUG(0, ("gss_set_cred_option(GSS_KRB5_CRED_NO_CI_FLAGS_X), " 285 "failed with [%s]\n", 286 gse_errstr(gse_ctx, gss_maj, gss_min))); 287 status = NT_STATUS_INTERNAL_ERROR; 288 goto err_out; 289 } 290 #endif 278 291 279 292 *_gse_ctx = gse_ctx; … … 287 300 } 288 301 289 NTSTATUS gse_get_client_auth_token(TALLOC_CTX *mem_ctx,290 291 292 302 static NTSTATUS gse_get_client_auth_token(TALLOC_CTX *mem_ctx, 303 struct gse_context *gse_ctx, 304 const DATA_BLOB *token_in, 305 DATA_BLOB *token_out) 293 306 { 294 307 OM_uint32 gss_maj, gss_min; … … 297 310 DATA_BLOB blob = data_blob_null; 298 311 NTSTATUS status; 312 OM_uint32 time_rec = 0; 313 struct timeval tv; 299 314 300 315 in_data.value = token_in->data; … … 303 318 gss_maj = gss_init_sec_context(&gss_min, 304 319 gse_ctx->creds, 305 &gse_ctx->gss _ctx,320 &gse_ctx->gssapi_context, 306 321 gse_ctx->server_name, 307 322 &gse_ctx->gss_mech, 308 gse_ctx->gss_ c_flags,323 gse_ctx->gss_want_flags, 309 324 0, GSS_C_NO_CHANNEL_BINDINGS, 310 325 &in_data, NULL, &out_data, 311 NULL, NULL);326 &gse_ctx->gss_got_flags, &time_rec); 312 327 switch (gss_maj) { 313 328 case GSS_S_COMPLETE: 314 329 /* we are done with it */ 315 gse_ctx->more_processing = false; 330 tv = timeval_current_ofs(time_rec, 0); 331 gse_ctx->expire_time = timeval_to_nttime(&tv); 332 316 333 status = NT_STATUS_OK; 317 334 break; 318 335 case GSS_S_CONTINUE_NEEDED: 319 336 /* we will need a third leg */ 320 gse_ctx->more_processing = true; 321 /* status = NT_STATUS_MORE_PROCESSING_REQUIRED; */ 322 status = NT_STATUS_OK; 337 status = NT_STATUS_MORE_PROCESSING_REQUIRED; 323 338 break; 324 339 default: … … 329 344 } 330 345 331 blob = data_blob_talloc(mem_ctx, out_data.value, out_data.length); 332 if (!blob.data) { 333 status = NT_STATUS_NO_MEMORY; 334 } 335 336 gss_maj = gss_release_buffer(&gss_min, &out_data); 346 /* we may be told to return nothing */ 347 if (out_data.length) { 348 blob = data_blob_talloc(mem_ctx, out_data.value, out_data.length); 349 if (!blob.data) { 350 status = NT_STATUS_NO_MEMORY; 351 } 352 353 gss_maj = gss_release_buffer(&gss_min, &out_data); 354 } 337 355 338 356 done: … … 341 359 } 342 360 343 NTSTATUS gse_init_server(TALLOC_CTX *mem_ctx, 344 bool do_sign, bool do_seal, 345 uint32_t add_gss_c_flags, 346 const char *keytab_name, 347 struct gse_context **_gse_ctx) 361 static NTSTATUS gse_init_server(TALLOC_CTX *mem_ctx, 362 bool do_sign, bool do_seal, 363 uint32_t add_gss_c_flags, 364 struct gse_context **_gse_ctx) 348 365 { 349 366 struct gse_context *gse_ctx; 350 367 OM_uint32 gss_maj, gss_min; 351 gss_OID_set_desc mech_set;352 368 krb5_error_code ret; 353 const char *ktname;354 369 NTSTATUS status; 355 370 … … 360 375 } 361 376 362 if (!keytab_name) { 363 ret = gse_krb5_get_server_keytab(gse_ctx->k5ctx, 364 &gse_ctx->keytab); 365 if (ret) { 366 status = NT_STATUS_INTERNAL_ERROR; 367 goto done; 368 } 369 ret = smb_krb5_keytab_name(gse_ctx, gse_ctx->k5ctx, 370 gse_ctx->keytab, &ktname); 371 if (ret) { 372 status = NT_STATUS_INTERNAL_ERROR; 373 goto done; 374 } 375 } else { 376 ktname = keytab_name; 377 } 378 377 ret = gse_krb5_get_server_keytab(gse_ctx->k5ctx, 378 &gse_ctx->keytab); 379 if (ret) { 380 status = NT_STATUS_INTERNAL_ERROR; 381 goto done; 382 } 383 384 #ifdef HAVE_GSS_KRB5_IMPORT_CRED 385 386 /* This creates a GSSAPI cred_id_t with the keytab set */ 387 gss_maj = gss_krb5_import_cred(&gss_min, NULL, NULL, gse_ctx->keytab, 388 &gse_ctx->creds); 389 390 if (gss_maj != 0 391 && gss_maj != (GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME)) { 392 DEBUG(0, ("gss_krb5_import_cred failed with [%s]\n", 393 gse_errstr(gse_ctx, gss_maj, gss_min))); 394 status = NT_STATUS_INTERNAL_ERROR; 395 goto done; 396 397 /* This is the error the MIT krb5 1.9 gives when it 398 * implements the function, but we do not specify the 399 * principal. However, when we specify the principal 400 * as host$@REALM the GSS acceptor fails with 'wrong 401 * principal in request'. Work around the issue by 402 * falling back to the alternate approach below. */ 403 } else if (gss_maj == (GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME)) 404 #endif 379 405 /* FIXME!!! 380 406 * This call sets the default keytab for the whole server, not 381 407 * just for this context. Need to find a way that does not alter 382 408 * the state of the whole server ... */ 383 ret = gsskrb5_register_acceptor_identity(ktname); 384 if (ret) { 385 status = NT_STATUS_INTERNAL_ERROR; 386 goto done; 387 } 388 389 mech_set.count = 1; 390 mech_set.elements = &gse_ctx->gss_mech; 391 392 gss_maj = gss_acquire_cred(&gss_min, 409 { 410 const char *ktname; 411 gss_OID_set_desc mech_set; 412 413 ret = smb_krb5_keytab_name(gse_ctx, gse_ctx->k5ctx, 414 gse_ctx->keytab, &ktname); 415 if (ret) { 416 status = NT_STATUS_INTERNAL_ERROR; 417 goto done; 418 } 419 420 ret = gsskrb5_register_acceptor_identity(ktname); 421 if (ret) { 422 status = NT_STATUS_INTERNAL_ERROR; 423 goto done; 424 } 425 426 mech_set.count = 1; 427 mech_set.elements = &gse_ctx->gss_mech; 428 429 gss_maj = gss_acquire_cred(&gss_min, 393 430 GSS_C_NO_NAME, 394 431 GSS_C_INDEFINITE, … … 397 434 &gse_ctx->creds, 398 435 NULL, NULL); 399 if (gss_maj) { 400 DEBUG(0, ("gss_acquire_creds failed with [%s]\n", 401 gse_errstr(gse_ctx, gss_maj, gss_min))); 402 status = NT_STATUS_INTERNAL_ERROR; 403 goto done; 436 437 if (gss_maj) { 438 DEBUG(0, ("gss_acquire_creds failed with [%s]\n", 439 gse_errstr(gse_ctx, gss_maj, gss_min))); 440 status = NT_STATUS_INTERNAL_ERROR; 441 goto done; 442 } 404 443 } 405 444 … … 415 454 } 416 455 417 NTSTATUS gse_get_server_auth_token(TALLOC_CTX *mem_ctx,418 419 420 456 static NTSTATUS gse_get_server_auth_token(TALLOC_CTX *mem_ctx, 457 struct gse_context *gse_ctx, 458 const DATA_BLOB *token_in, 459 DATA_BLOB *token_out) 421 460 { 422 461 OM_uint32 gss_maj, gss_min; … … 425 464 DATA_BLOB blob = data_blob_null; 426 465 NTSTATUS status; 466 OM_uint32 time_rec = 0; 467 struct timeval tv; 427 468 428 469 in_data.value = token_in->data; … … 430 471 431 472 gss_maj = gss_accept_sec_context(&gss_min, 432 &gse_ctx->gss _ctx,473 &gse_ctx->gssapi_context, 433 474 gse_ctx->creds, 434 475 &in_data, … … 437 478 &gse_ctx->ret_mech, 438 479 &out_data, 439 &gse_ctx->ret_flags, NULL, 440 &gse_ctx->delegated_creds); 480 &gse_ctx->gss_got_flags, 481 &time_rec, 482 &gse_ctx->delegated_cred_handle); 441 483 switch (gss_maj) { 442 484 case GSS_S_COMPLETE: 443 485 /* we are done with it */ 444 gse_ctx->more_processing = false; 445 gse_ctx->authenticated = true; 486 tv = timeval_current_ofs(time_rec, 0); 487 gse_ctx->expire_time = timeval_to_nttime(&tv); 488 446 489 status = NT_STATUS_OK; 447 490 break; 448 491 case GSS_S_CONTINUE_NEEDED: 449 492 /* we will need a third leg */ 450 gse_ctx->more_processing = true; 451 /* status = NT_STATUS_MORE_PROCESSING_REQUIRED; */ 452 status = NT_STATUS_OK; 493 status = NT_STATUS_MORE_PROCESSING_REQUIRED; 453 494 break; 454 495 default: 455 DEBUG( 0, ("gss_init_sec_context failed with [%s]\n",496 DEBUG(1, ("gss_accept_sec_context failed with [%s]\n", 456 497 gse_errstr(talloc_tos(), gss_maj, gss_min))); 457 498 458 if (gse_ctx->gss _ctx) {499 if (gse_ctx->gssapi_context) { 459 500 gss_delete_sec_context(&gss_min, 460 &gse_ctx->gss _ctx,501 &gse_ctx->gssapi_context, 461 502 GSS_C_NO_BUFFER); 462 503 } 463 504 464 status = NT_STATUS_INTERNAL_ERROR; 465 goto done; 505 /* 506 * If we got an output token, make Windows aware of it 507 * by telling it that more processing is needed 508 */ 509 if (out_data.length > 0) { 510 status = NT_STATUS_MORE_PROCESSING_REQUIRED; 511 /* Fall through to handle the out token */ 512 } else { 513 status = NT_STATUS_LOGON_FAILURE; 514 goto done; 515 } 466 516 } 467 517 … … 481 531 } 482 532 483 NTSTATUS gse_verify_server_auth_flags(struct gse_context *gse_ctx)484 {485 if (!gse_ctx->authenticated) {486 return NT_STATUS_INVALID_HANDLE;487 }488 489 if (memcmp(gse_ctx->ret_mech,490 gss_mech_krb5, sizeof(gss_OID_desc)) != 0) {491 return NT_STATUS_ACCESS_DENIED;492 }493 494 /* GSS_C_MUTUAL_FLAG */495 if (gse_ctx->gss_c_flags & GSS_C_MUTUAL_FLAG) {496 if (!(gse_ctx->ret_flags & GSS_C_MUTUAL_FLAG)) {497 return NT_STATUS_ACCESS_DENIED;498 }499 }500 501 /* GSS_C_DELEG_FLAG */502 /* GSS_C_DELEG_POLICY_FLAG */503 /* GSS_C_REPLAY_FLAG */504 /* GSS_C_SEQUENCE_FLAG */505 506 /* GSS_C_INTEG_FLAG */507 if (gse_ctx->gss_c_flags & GSS_C_INTEG_FLAG) {508 if (!(gse_ctx->ret_flags & GSS_C_INTEG_FLAG)) {509 return NT_STATUS_ACCESS_DENIED;510 }511 }512 513 /* GSS_C_CONF_FLAG */514 if (gse_ctx->gss_c_flags & GSS_C_CONF_FLAG) {515 if (!(gse_ctx->ret_flags & GSS_C_CONF_FLAG)) {516 return NT_STATUS_ACCESS_DENIED;517 }518 }519 520 return NT_STATUS_OK;521 }522 523 533 static char *gse_errstr(TALLOC_CTX *mem_ctx, OM_uint32 maj, OM_uint32 min) 524 534 { … … 536 546 GSS_C_NO_OID, &msg_ctx, &msg_maj); 537 547 if (gss_maj) { 548 goto done; 549 } 550 errstr = talloc_strndup(mem_ctx, 551 (char *)msg_maj.value, 552 msg_maj.length); 553 if (!errstr) { 538 554 goto done; 539 555 } … … 545 561 } 546 562 547 errstr = talloc_strndup(mem_ctx,548 (char *)msg_maj.value,549 msg_maj.length);550 if (!errstr) {551 goto done;552 }553 563 errstr = talloc_strdup_append_buffer(errstr, ": "); 554 564 if (!errstr) { … … 572 582 } 573 583 574 bool gse_require_more_processing(struct gse_context *gse_ctx) 575 { 576 return gse_ctx->more_processing; 577 } 578 579 DATA_BLOB gse_get_session_key(TALLOC_CTX *mem_ctx, 580 struct gse_context *gse_ctx) 581 { 582 OM_uint32 gss_min, gss_maj; 583 gss_buffer_set_t set = GSS_C_NO_BUFFER_SET; 584 DATA_BLOB ret; 585 586 gss_maj = gss_inquire_sec_context_by_oid( 587 &gss_min, gse_ctx->gss_ctx, 588 &gse_sesskey_inq_oid, &set); 589 if (gss_maj) { 590 DEBUG(0, ("gss_inquire_sec_context_by_oid failed [%s]\n", 591 gse_errstr(talloc_tos(), gss_maj, gss_min))); 592 return data_blob_null; 593 } 594 595 if ((set == GSS_C_NO_BUFFER_SET) || 596 (set->count != 2) || 597 (memcmp(set->elements[1].value, 598 gse_sesskeytype_oid.elements, 599 gse_sesskeytype_oid.length) != 0)) { 600 DEBUG(0, ("gss_inquire_sec_context_by_oid returned unknown " 601 "OID for data in results:\n")); 602 dump_data(1, (uint8_t *)set->elements[1].value, 603 set->elements[1].length); 604 return data_blob_null; 605 } 606 607 ret = data_blob_talloc(mem_ctx, set->elements[0].value, 608 set->elements[0].length); 609 610 gss_maj = gss_release_buffer_set(&gss_min, &set); 611 return ret; 612 } 613 614 NTSTATUS gse_get_client_name(struct gse_context *gse_ctx, 615 TALLOC_CTX *mem_ctx, char **cli_name) 616 { 617 OM_uint32 gss_min, gss_maj; 618 gss_buffer_desc name_buffer; 619 620 if (!gse_ctx->authenticated) { 584 static NTSTATUS gensec_gse_client_start(struct gensec_security *gensec_security) 585 { 586 struct gse_context *gse_ctx; 587 struct cli_credentials *creds = gensec_get_credentials(gensec_security); 588 NTSTATUS nt_status; 589 OM_uint32 want_flags = 0; 590 bool do_sign = false, do_seal = false; 591 const char *hostname = gensec_get_target_hostname(gensec_security); 592 const char *service = gensec_get_target_service(gensec_security); 593 const char *username = cli_credentials_get_username(creds); 594 const char *password = cli_credentials_get_password(creds); 595 596 if (!hostname) { 597 DEBUG(1, ("Could not determine hostname for target computer, cannot use kerberos\n")); 598 return NT_STATUS_INVALID_PARAMETER; 599 } 600 if (is_ipaddress(hostname)) { 601 DEBUG(2, ("Cannot do GSE to an IP address\n")); 602 return NT_STATUS_INVALID_PARAMETER; 603 } 604 if (strcmp(hostname, "localhost") == 0) { 605 DEBUG(2, ("GSE to 'localhost' does not make sense\n")); 606 return NT_STATUS_INVALID_PARAMETER; 607 } 608 609 if (gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) { 610 do_sign = true; 611 } 612 if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { 613 do_sign = true; 614 } 615 if (gensec_security->want_features & GENSEC_FEATURE_SEAL) { 616 do_seal = true; 617 } 618 if (gensec_security->want_features & GENSEC_FEATURE_DCE_STYLE) { 619 want_flags |= GSS_C_DCE_STYLE; 620 } 621 622 nt_status = gse_init_client(gensec_security, do_sign, do_seal, NULL, 623 hostname, service, 624 username, password, want_flags, 625 &gse_ctx); 626 if (!NT_STATUS_IS_OK(nt_status)) { 627 return nt_status; 628 } 629 gensec_security->private_data = gse_ctx; 630 return NT_STATUS_OK; 631 } 632 633 static NTSTATUS gensec_gse_server_start(struct gensec_security *gensec_security) 634 { 635 struct gse_context *gse_ctx; 636 NTSTATUS nt_status; 637 OM_uint32 want_flags = 0; 638 bool do_sign = false, do_seal = false; 639 640 if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { 641 do_sign = true; 642 } 643 if (gensec_security->want_features & GENSEC_FEATURE_SEAL) { 644 do_seal = true; 645 } 646 if (gensec_security->want_features & GENSEC_FEATURE_DCE_STYLE) { 647 want_flags |= GSS_C_DCE_STYLE; 648 } 649 650 nt_status = gse_init_server(gensec_security, do_sign, do_seal, want_flags, 651 &gse_ctx); 652 if (!NT_STATUS_IS_OK(nt_status)) { 653 return nt_status; 654 } 655 gensec_security->private_data = gse_ctx; 656 return NT_STATUS_OK; 657 } 658 659 /** 660 * Next state function for the GSE GENSEC mechanism 661 * 662 * @param gensec_gse_state GSE State 663 * @param mem_ctx The TALLOC_CTX for *out to be allocated on 664 * @param in The request, as a DATA_BLOB 665 * @param out The reply, as an talloc()ed DATA_BLOB, on *mem_ctx 666 * @return Error, MORE_PROCESSING_REQUIRED if a reply is sent, 667 * or NT_STATUS_OK if the user is authenticated. 668 */ 669 670 static NTSTATUS gensec_gse_update(struct gensec_security *gensec_security, 671 TALLOC_CTX *mem_ctx, 672 struct tevent_context *ev, 673 const DATA_BLOB in, DATA_BLOB *out) 674 { 675 NTSTATUS status; 676 struct gse_context *gse_ctx = 677 talloc_get_type_abort(gensec_security->private_data, 678 struct gse_context); 679 680 switch (gensec_security->gensec_role) { 681 case GENSEC_CLIENT: 682 status = gse_get_client_auth_token(mem_ctx, gse_ctx, 683 &in, out); 684 break; 685 case GENSEC_SERVER: 686 status = gse_get_server_auth_token(mem_ctx, gse_ctx, 687 &in, out); 688 break; 689 } 690 if (!NT_STATUS_IS_OK(status)) { 691 return status; 692 } 693 694 return NT_STATUS_OK; 695 } 696 697 static NTSTATUS gensec_gse_wrap(struct gensec_security *gensec_security, 698 TALLOC_CTX *mem_ctx, 699 const DATA_BLOB *in, 700 DATA_BLOB *out) 701 { 702 struct gse_context *gse_ctx = 703 talloc_get_type_abort(gensec_security->private_data, 704 struct gse_context); 705 OM_uint32 maj_stat, min_stat; 706 gss_buffer_desc input_token, output_token; 707 int conf_state; 708 input_token.length = in->length; 709 input_token.value = in->data; 710 711 maj_stat = gss_wrap(&min_stat, 712 gse_ctx->gssapi_context, 713 gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL), 714 GSS_C_QOP_DEFAULT, 715 &input_token, 716 &conf_state, 717 &output_token); 718 if (GSS_ERROR(maj_stat)) { 719 DEBUG(0, ("gensec_gse_wrap: GSS Wrap failed: %s\n", 720 gse_errstr(talloc_tos(), maj_stat, min_stat))); 621 721 return NT_STATUS_ACCESS_DENIED; 622 722 } 623 723 624 if (!gse_ctx->client_name) { 625 return NT_STATUS_NOT_FOUND; 626 } 627 628 /* TODO: check OID matches KRB5 Principal Name OID ? */ 629 630 gss_maj = gss_display_name(&gss_min, 631 gse_ctx->client_name, 632 &name_buffer, NULL); 633 if (gss_maj) { 634 DEBUG(0, ("gss_display_name failed [%s]\n", 635 gse_errstr(talloc_tos(), gss_maj, gss_min))); 636 return NT_STATUS_INTERNAL_ERROR; 637 } 638 639 *cli_name = talloc_strndup(talloc_tos(), 640 (char *)name_buffer.value, 641 name_buffer.length); 642 643 gss_maj = gss_release_buffer(&gss_min, &name_buffer); 644 645 if (!*cli_name) { 724 *out = data_blob_talloc(mem_ctx, output_token.value, output_token.length); 725 gss_release_buffer(&min_stat, &output_token); 726 727 if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL) 728 && !conf_state) { 729 return NT_STATUS_ACCESS_DENIED; 730 } 731 return NT_STATUS_OK; 732 } 733 734 static NTSTATUS gensec_gse_unwrap(struct gensec_security *gensec_security, 735 TALLOC_CTX *mem_ctx, 736 const DATA_BLOB *in, 737 DATA_BLOB *out) 738 { 739 struct gse_context *gse_ctx = 740 talloc_get_type_abort(gensec_security->private_data, 741 struct gse_context); 742 OM_uint32 maj_stat, min_stat; 743 gss_buffer_desc input_token, output_token; 744 int conf_state; 745 gss_qop_t qop_state; 746 input_token.length = in->length; 747 input_token.value = in->data; 748 749 maj_stat = gss_unwrap(&min_stat, 750 gse_ctx->gssapi_context, 751 &input_token, 752 &output_token, 753 &conf_state, 754 &qop_state); 755 if (GSS_ERROR(maj_stat)) { 756 DEBUG(0, ("gensec_gse_unwrap: GSS UnWrap failed: %s\n", 757 gse_errstr(talloc_tos(), maj_stat, min_stat))); 758 return NT_STATUS_ACCESS_DENIED; 759 } 760 761 *out = data_blob_talloc(mem_ctx, output_token.value, output_token.length); 762 gss_release_buffer(&min_stat, &output_token); 763 764 if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL) 765 && !conf_state) { 766 return NT_STATUS_ACCESS_DENIED; 767 } 768 return NT_STATUS_OK; 769 } 770 771 static NTSTATUS gensec_gse_seal_packet(struct gensec_security *gensec_security, 772 TALLOC_CTX *mem_ctx, 773 uint8_t *data, size_t length, 774 const uint8_t *whole_pdu, size_t pdu_length, 775 DATA_BLOB *sig) 776 { 777 struct gse_context *gse_ctx = 778 talloc_get_type_abort(gensec_security->private_data, 779 struct gse_context); 780 bool hdr_signing = false; 781 size_t sig_size = 0; 782 NTSTATUS status; 783 784 if (gensec_security->want_features & GENSEC_FEATURE_SIGN_PKT_HEADER) { 785 hdr_signing = true; 786 } 787 788 sig_size = gensec_gse_sig_size(gensec_security, length); 789 790 status = gssapi_seal_packet(gse_ctx->gssapi_context, 791 &gse_ctx->gss_mech, 792 hdr_signing, sig_size, 793 data, length, 794 whole_pdu, pdu_length, 795 mem_ctx, sig); 796 if (!NT_STATUS_IS_OK(status)) { 797 DEBUG(0, ("gssapi_seal_packet(hdr_signing=%u,sig_size=%zu," 798 "data=%zu,pdu=%zu) failed: %s\n", 799 hdr_signing, sig_size, length, pdu_length, 800 nt_errstr(status))); 801 return status; 802 } 803 804 return NT_STATUS_OK; 805 } 806 807 static NTSTATUS gensec_gse_unseal_packet(struct gensec_security *gensec_security, 808 uint8_t *data, size_t length, 809 const uint8_t *whole_pdu, size_t pdu_length, 810 const DATA_BLOB *sig) 811 { 812 struct gse_context *gse_ctx = 813 talloc_get_type_abort(gensec_security->private_data, 814 struct gse_context); 815 bool hdr_signing = false; 816 NTSTATUS status; 817 818 if (gensec_security->want_features & GENSEC_FEATURE_SIGN_PKT_HEADER) { 819 hdr_signing = true; 820 } 821 822 status = gssapi_unseal_packet(gse_ctx->gssapi_context, 823 &gse_ctx->gss_mech, 824 hdr_signing, 825 data, length, 826 whole_pdu, pdu_length, 827 sig); 828 if (!NT_STATUS_IS_OK(status)) { 829 DEBUG(0, ("gssapi_unseal_packet(hdr_signing=%u,sig_size=%zu," 830 "data=%zu,pdu=%zu) failed: %s\n", 831 hdr_signing, sig->length, length, pdu_length, 832 nt_errstr(status))); 833 return status; 834 } 835 836 return NT_STATUS_OK; 837 } 838 839 static NTSTATUS gensec_gse_sign_packet(struct gensec_security *gensec_security, 840 TALLOC_CTX *mem_ctx, 841 const uint8_t *data, size_t length, 842 const uint8_t *whole_pdu, size_t pdu_length, 843 DATA_BLOB *sig) 844 { 845 struct gse_context *gse_ctx = 846 talloc_get_type_abort(gensec_security->private_data, 847 struct gse_context); 848 bool hdr_signing = false; 849 NTSTATUS status; 850 851 if (gensec_security->want_features & GENSEC_FEATURE_SIGN_PKT_HEADER) { 852 hdr_signing = true; 853 } 854 855 status = gssapi_sign_packet(gse_ctx->gssapi_context, 856 &gse_ctx->gss_mech, 857 hdr_signing, 858 data, length, 859 whole_pdu, pdu_length, 860 mem_ctx, sig); 861 if (!NT_STATUS_IS_OK(status)) { 862 DEBUG(0, ("gssapi_sign_packet(hdr_signing=%u," 863 "data=%zu,pdu=%zu) failed: %s\n", 864 hdr_signing, length, pdu_length, 865 nt_errstr(status))); 866 return status; 867 } 868 869 return NT_STATUS_OK; 870 } 871 872 static NTSTATUS gensec_gse_check_packet(struct gensec_security *gensec_security, 873 const uint8_t *data, size_t length, 874 const uint8_t *whole_pdu, size_t pdu_length, 875 const DATA_BLOB *sig) 876 { 877 struct gse_context *gse_ctx = 878 talloc_get_type_abort(gensec_security->private_data, 879 struct gse_context); 880 bool hdr_signing = false; 881 NTSTATUS status; 882 883 if (gensec_security->want_features & GENSEC_FEATURE_SIGN_PKT_HEADER) { 884 hdr_signing = true; 885 } 886 887 status = gssapi_check_packet(gse_ctx->gssapi_context, 888 &gse_ctx->gss_mech, 889 hdr_signing, 890 data, length, 891 whole_pdu, pdu_length, 892 sig); 893 if (!NT_STATUS_IS_OK(status)) { 894 DEBUG(0, ("gssapi_check_packet(hdr_signing=%u,sig_size=%zu" 895 "data=%zu,pdu=%zu) failed: %s\n", 896 hdr_signing, sig->length, length, pdu_length, 897 nt_errstr(status))); 898 return status; 899 } 900 901 return NT_STATUS_OK; 902 } 903 904 /* Try to figure out what features we actually got on the connection */ 905 static bool gensec_gse_have_feature(struct gensec_security *gensec_security, 906 uint32_t feature) 907 { 908 struct gse_context *gse_ctx = 909 talloc_get_type_abort(gensec_security->private_data, 910 struct gse_context); 911 912 if (feature & GENSEC_FEATURE_SESSION_KEY) { 913 return gse_ctx->gss_got_flags & GSS_C_INTEG_FLAG; 914 } 915 if (feature & GENSEC_FEATURE_SIGN) { 916 return gse_ctx->gss_got_flags & GSS_C_INTEG_FLAG; 917 } 918 if (feature & GENSEC_FEATURE_SEAL) { 919 return gse_ctx->gss_got_flags & GSS_C_CONF_FLAG; 920 } 921 if (feature & GENSEC_FEATURE_DCE_STYLE) { 922 return gse_ctx->gss_got_flags & GSS_C_DCE_STYLE; 923 } 924 if (feature & GENSEC_FEATURE_NEW_SPNEGO) { 925 NTSTATUS status; 926 uint32_t keytype; 927 928 if (!(gse_ctx->gss_got_flags & GSS_C_INTEG_FLAG)) { 929 return false; 930 } 931 932 status = gssapi_get_session_key(talloc_tos(), 933 gse_ctx->gssapi_context, NULL, &keytype); 934 /* 935 * We should do a proper sig on the mechListMic unless 936 * we know we have to be backwards compatible with 937 * earlier windows versions. 938 * 939 * Negotiating a non-krb5 940 * mech for example should be regarded as having 941 * NEW_SPNEGO 942 */ 943 if (NT_STATUS_IS_OK(status)) { 944 switch (keytype) { 945 case ENCTYPE_DES_CBC_CRC: 946 case ENCTYPE_DES_CBC_MD5: 947 case ENCTYPE_ARCFOUR_HMAC: 948 case ENCTYPE_DES3_CBC_SHA1: 949 return false; 950 } 951 } 952 return true; 953 } 954 /* We can always do async (rather than strict request/reply) packets. */ 955 if (feature & GENSEC_FEATURE_ASYNC_REPLIES) { 956 return true; 957 } 958 if (feature & GENSEC_FEATURE_SIGN_PKT_HEADER) { 959 if (gensec_security->want_features & GENSEC_FEATURE_SEAL) { 960 return true; 961 } 962 963 if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { 964 return true; 965 } 966 967 return false; 968 } 969 return false; 970 } 971 972 static NTTIME gensec_gse_expire_time(struct gensec_security *gensec_security) 973 { 974 struct gse_context *gse_ctx = 975 talloc_get_type_abort(gensec_security->private_data, 976 struct gse_context); 977 978 return gse_ctx->expire_time; 979 } 980 981 /* 982 * Extract the 'sesssion key' needed by SMB signing and ncacn_np 983 * (for encrypting some passwords). 984 * 985 * This breaks all the abstractions, but what do you expect... 986 */ 987 static NTSTATUS gensec_gse_session_key(struct gensec_security *gensec_security, 988 TALLOC_CTX *mem_ctx, 989 DATA_BLOB *session_key) 990 { 991 struct gse_context *gse_ctx = 992 talloc_get_type_abort(gensec_security->private_data, 993 struct gse_context); 994 995 return gssapi_get_session_key(mem_ctx, gse_ctx->gssapi_context, session_key, NULL); 996 } 997 998 /* Get some basic (and authorization) information about the user on 999 * this session. This uses either the PAC (if present) or a local 1000 * database lookup */ 1001 static NTSTATUS gensec_gse_session_info(struct gensec_security *gensec_security, 1002 TALLOC_CTX *mem_ctx, 1003 struct auth_session_info **_session_info) 1004 { 1005 struct gse_context *gse_ctx = 1006 talloc_get_type_abort(gensec_security->private_data, 1007 struct gse_context); 1008 NTSTATUS nt_status; 1009 TALLOC_CTX *tmp_ctx; 1010 struct auth_session_info *session_info = NULL; 1011 OM_uint32 maj_stat, min_stat; 1012 DATA_BLOB pac_blob, *pac_blob_ptr = NULL; 1013 1014 gss_buffer_desc name_token; 1015 char *principal_string; 1016 1017 tmp_ctx = talloc_named(mem_ctx, 0, "gensec_gse_session_info context"); 1018 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx); 1019 1020 maj_stat = gss_display_name(&min_stat, 1021 gse_ctx->client_name, 1022 &name_token, 1023 NULL); 1024 if (GSS_ERROR(maj_stat)) { 1025 DEBUG(1, ("GSS display_name failed: %s\n", 1026 gse_errstr(talloc_tos(), maj_stat, min_stat))); 1027 talloc_free(tmp_ctx); 1028 return NT_STATUS_FOOBAR; 1029 } 1030 1031 principal_string = talloc_strndup(tmp_ctx, 1032 (const char *)name_token.value, 1033 name_token.length); 1034 1035 gss_release_buffer(&min_stat, &name_token); 1036 1037 if (!principal_string) { 1038 talloc_free(tmp_ctx); 646 1039 return NT_STATUS_NO_MEMORY; 647 1040 } 648 1041 1042 nt_status = gssapi_obtain_pac_blob(tmp_ctx, gse_ctx->gssapi_context, 1043 gse_ctx->client_name, 1044 &pac_blob); 1045 1046 /* IF we have the PAC - otherwise we need to get this 1047 * data from elsewere 1048 */ 1049 if (NT_STATUS_IS_OK(nt_status)) { 1050 pac_blob_ptr = &pac_blob; 1051 } 1052 nt_status = gensec_generate_session_info_pac(tmp_ctx, 1053 gensec_security, 1054 NULL, 1055 pac_blob_ptr, principal_string, 1056 gensec_get_remote_address(gensec_security), 1057 &session_info); 1058 if (!NT_STATUS_IS_OK(nt_status)) { 1059 talloc_free(tmp_ctx); 1060 return nt_status; 1061 } 1062 1063 nt_status = gensec_gse_session_key(gensec_security, session_info, 1064 &session_info->session_key); 1065 if (!NT_STATUS_IS_OK(nt_status)) { 1066 talloc_free(tmp_ctx); 1067 return nt_status; 1068 } 1069 1070 *_session_info = talloc_move(mem_ctx, &session_info); 1071 talloc_free(tmp_ctx); 1072 649 1073 return NT_STATUS_OK; 650 1074 } 651 1075 652 NTSTATUS gse_get_authz_data(struct gse_context *gse_ctx, 653 TALLOC_CTX *mem_ctx, DATA_BLOB *pac) 654 { 655 OM_uint32 gss_min, gss_maj; 656 gss_buffer_set_t set = GSS_C_NO_BUFFER_SET; 657 658 if (!gse_ctx->authenticated) { 659 return NT_STATUS_ACCESS_DENIED; 660 } 661 662 gss_maj = gss_inquire_sec_context_by_oid( 663 &gss_min, gse_ctx->gss_ctx, 664 &gse_authz_data_oid, &set); 665 if (gss_maj) { 666 DEBUG(0, ("gss_inquire_sec_context_by_oid failed [%s]\n", 667 gse_errstr(talloc_tos(), gss_maj, gss_min))); 668 return NT_STATUS_NOT_FOUND; 669 } 670 671 if (set == GSS_C_NO_BUFFER_SET) { 672 DEBUG(0, ("gss_inquire_sec_context_by_oid returned unknown " 673 "data in results.\n")); 674 return NT_STATUS_INTERNAL_ERROR; 675 } 676 677 /* for now we just hope it is the first value */ 678 *pac = data_blob_talloc(mem_ctx, 679 set->elements[0].value, 680 set->elements[0].length); 681 682 gss_maj = gss_release_buffer_set(&gss_min, &set); 683 684 return NT_STATUS_OK; 685 } 686 687 NTSTATUS gse_get_pac_blob(struct gse_context *gse_ctx, 688 TALLOC_CTX *mem_ctx, DATA_BLOB *pac_blob) 689 { 690 OM_uint32 gss_min, gss_maj; 691 /* 692 * gss_get_name_attribute() in MIT krb5 1.10.0 can return unintialized pac_display_buffer 693 * and later gss_release_buffer() will crash on attempting to release it. 694 * 695 * So always initialize the buffer descriptors. 696 * 697 * See following links for more details: 698 * http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=658514 699 * http://krbdev.mit.edu/rt/Ticket/Display.html?user=guest&pass=guest&id=7087 700 */ 701 gss_buffer_desc pac_buffer = { 702 .value = NULL, 703 .length = 0 704 }; 705 gss_buffer_desc pac_display_buffer = { 706 .value = NULL, 707 .length = 0 708 }; 709 gss_buffer_desc pac_name = { 710 .value = discard_const_p(char, "urn:mspac:"), 711 .length = sizeof("urn:mspac:") - 1 712 }; 713 int more = -1; 714 int authenticated = false; 715 int complete = false; 716 NTSTATUS status; 717 718 if (!gse_ctx->authenticated) { 719 return NT_STATUS_ACCESS_DENIED; 720 } 721 722 gss_maj = gss_get_name_attribute(&gss_min, 723 gse_ctx->client_name, &pac_name, 724 &authenticated, &complete, 725 &pac_buffer, &pac_display_buffer, 726 &more); 727 728 if (gss_maj != 0) { 729 DEBUG(0, ("obtaining PAC via GSSAPI gss_get_name_attribute " 730 "failed: %s\n", 731 gse_errstr(mem_ctx, gss_maj, gss_min))); 732 return NT_STATUS_ACCESS_DENIED; 733 } 734 735 if (authenticated && complete) { 736 /* The PAC blob is returned directly */ 737 *pac_blob = data_blob_talloc(mem_ctx, 738 pac_buffer.value, 739 pac_buffer.length); 740 if (!pac_blob->data) { 741 status = NT_STATUS_NO_MEMORY; 742 } else { 743 status = NT_STATUS_OK; 744 } 745 746 gss_maj = gss_release_buffer(&gss_min, &pac_buffer); 747 gss_maj = gss_release_buffer(&gss_min, &pac_display_buffer); 748 749 return status; 750 } 751 752 DEBUG(0, ("obtaining PAC via GSSAPI failed: authenticated: %s, " 753 "complete: %s, more: %s\n", 754 authenticated ? "true" : "false", 755 complete ? "true" : "false", 756 more ? "true" : "false")); 757 758 return NT_STATUS_ACCESS_DENIED; 759 } 760 761 size_t gse_get_signature_length(struct gse_context *gse_ctx, 762 int seal, size_t payload_size) 763 { 764 OM_uint32 gss_min, gss_maj; 765 gss_iov_buffer_desc iov[2]; 766 uint8_t fakebuf[payload_size]; 767 int sealed; 768 769 iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER; 770 iov[0].buffer.value = NULL; 771 iov[0].buffer.length = 0; 772 iov[1].type = GSS_IOV_BUFFER_TYPE_DATA; 773 iov[1].buffer.value = fakebuf; 774 iov[1].buffer.length = payload_size; 775 776 gss_maj = gss_wrap_iov_length(&gss_min, gse_ctx->gss_ctx, 777 seal, GSS_C_QOP_DEFAULT, 778 &sealed, iov, 2); 779 if (gss_maj) { 780 DEBUG(0, ("gss_wrap_iov_length failed with [%s]\n", 781 gse_errstr(talloc_tos(), gss_maj, gss_min))); 1076 static size_t gensec_gse_max_input_size(struct gensec_security *gensec_security) 1077 { 1078 struct gse_context *gse_ctx = 1079 talloc_get_type_abort(gensec_security->private_data, 1080 struct gse_context); 1081 OM_uint32 maj_stat, min_stat; 1082 OM_uint32 max_input_size; 1083 1084 maj_stat = gss_wrap_size_limit(&min_stat, 1085 gse_ctx->gssapi_context, 1086 gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL), 1087 GSS_C_QOP_DEFAULT, 1088 gse_ctx->max_wrap_buf_size, 1089 &max_input_size); 1090 if (GSS_ERROR(maj_stat)) { 1091 TALLOC_CTX *mem_ctx = talloc_new(NULL); 1092 DEBUG(1, ("gensec_gssapi_max_input_size: determining signature size with gss_wrap_size_limit failed: %s\n", 1093 gse_errstr(mem_ctx, maj_stat, min_stat))); 1094 talloc_free(mem_ctx); 782 1095 return 0; 783 1096 } 784 1097 785 return iov[0].buffer.length; 786 } 787 788 NTSTATUS gse_seal(TALLOC_CTX *mem_ctx, struct gse_context *gse_ctx, 789 DATA_BLOB *data, DATA_BLOB *signature) 790 { 791 OM_uint32 gss_min, gss_maj; 792 gss_iov_buffer_desc iov[2]; 793 int req_seal = 1; /* setting to 1 means we request sign+seal */ 794 int sealed; 795 NTSTATUS status; 796 797 /* allocate the memory ourselves so we do not need to talloc_memdup */ 798 signature->length = gse_get_signature_length(gse_ctx, 1, data->length); 799 if (!signature->length) { 800 return NT_STATUS_INTERNAL_ERROR; 801 } 802 signature->data = (uint8_t *)talloc_size(mem_ctx, signature->length); 803 if (!signature->data) { 804 return NT_STATUS_NO_MEMORY; 805 } 806 iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER; 807 iov[0].buffer.value = signature->data; 808 iov[0].buffer.length = signature->length; 809 810 /* data is encrypted in place, which is ok */ 811 iov[1].type = GSS_IOV_BUFFER_TYPE_DATA; 812 iov[1].buffer.value = data->data; 813 iov[1].buffer.length = data->length; 814 815 gss_maj = gss_wrap_iov(&gss_min, gse_ctx->gss_ctx, 816 req_seal, GSS_C_QOP_DEFAULT, 817 &sealed, iov, 2); 818 if (gss_maj) { 819 DEBUG(0, ("gss_wrap_iov failed with [%s]\n", 820 gse_errstr(talloc_tos(), gss_maj, gss_min))); 821 status = NT_STATUS_ACCESS_DENIED; 822 goto done; 823 } 824 825 if (!sealed) { 826 DEBUG(0, ("gss_wrap_iov says data was not sealed!\n")); 827 status = NT_STATUS_ACCESS_DENIED; 828 goto done; 829 } 830 831 status = NT_STATUS_OK; 832 833 DEBUG(10, ("Sealed %d bytes, and got %d bytes header/signature.\n", 834 (int)iov[1].buffer.length, (int)iov[0].buffer.length)); 835 836 done: 837 return status; 838 } 839 840 NTSTATUS gse_unseal(TALLOC_CTX *mem_ctx, struct gse_context *gse_ctx, 841 DATA_BLOB *data, DATA_BLOB *signature) 842 { 843 OM_uint32 gss_min, gss_maj; 844 gss_iov_buffer_desc iov[2]; 845 int sealed; 846 NTSTATUS status; 847 848 iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER; 849 iov[0].buffer.value = signature->data; 850 iov[0].buffer.length = signature->length; 851 852 /* data is decrypted in place, which is ok */ 853 iov[1].type = GSS_IOV_BUFFER_TYPE_DATA; 854 iov[1].buffer.value = data->data; 855 iov[1].buffer.length = data->length; 856 857 gss_maj = gss_unwrap_iov(&gss_min, gse_ctx->gss_ctx, 858 &sealed, NULL, iov, 2); 859 if (gss_maj) { 860 DEBUG(0, ("gss_unwrap_iov failed with [%s]\n", 861 gse_errstr(talloc_tos(), gss_maj, gss_min))); 862 status = NT_STATUS_ACCESS_DENIED; 863 goto done; 864 } 865 866 if (!sealed) { 867 DEBUG(0, ("gss_unwrap_iov says data is not sealed!\n")); 868 status = NT_STATUS_ACCESS_DENIED; 869 goto done; 870 } 871 872 status = NT_STATUS_OK; 873 874 DEBUG(10, ("Unsealed %d bytes, with %d bytes header/signature.\n", 875 (int)iov[1].buffer.length, (int)iov[0].buffer.length)); 876 877 done: 878 return status; 879 } 880 881 NTSTATUS gse_sign(TALLOC_CTX *mem_ctx, struct gse_context *gse_ctx, 882 DATA_BLOB *data, DATA_BLOB *signature) 883 { 884 OM_uint32 gss_min, gss_maj; 885 gss_buffer_desc in_data = { 0, NULL }; 886 gss_buffer_desc out_data = { 0, NULL}; 887 NTSTATUS status; 888 889 in_data.value = data->data; 890 in_data.length = data->length; 891 892 gss_maj = gss_get_mic(&gss_min, gse_ctx->gss_ctx, 893 GSS_C_QOP_DEFAULT, 894 &in_data, &out_data); 895 if (gss_maj) { 896 DEBUG(0, ("gss_get_mic failed with [%s]\n", 897 gse_errstr(talloc_tos(), gss_maj, gss_min))); 898 status = NT_STATUS_ACCESS_DENIED; 899 goto done; 900 } 901 902 *signature = data_blob_talloc(mem_ctx, 903 out_data.value, out_data.length); 904 if (!signature->data) { 905 status = NT_STATUS_NO_MEMORY; 906 goto done; 907 } 908 909 status = NT_STATUS_OK; 910 911 done: 912 if (out_data.value) { 913 gss_maj = gss_release_buffer(&gss_min, &out_data); 914 } 915 return status; 916 } 917 918 NTSTATUS gse_sigcheck(TALLOC_CTX *mem_ctx, struct gse_context *gse_ctx, 919 DATA_BLOB *data, DATA_BLOB *signature) 920 { 921 OM_uint32 gss_min, gss_maj; 922 gss_buffer_desc in_data = { 0, NULL }; 923 gss_buffer_desc in_token = { 0, NULL}; 924 NTSTATUS status; 925 926 in_data.value = data->data; 927 in_data.length = data->length; 928 in_token.value = signature->data; 929 in_token.length = signature->length; 930 931 gss_maj = gss_verify_mic(&gss_min, gse_ctx->gss_ctx, 932 &in_data, &in_token, NULL); 933 if (gss_maj) { 934 DEBUG(0, ("gss_verify_mic failed with [%s]\n", 935 gse_errstr(talloc_tos(), gss_maj, gss_min))); 936 status = NT_STATUS_ACCESS_DENIED; 937 goto done; 938 } 939 940 status = NT_STATUS_OK; 941 942 done: 943 return status; 944 } 945 946 #else 947 948 NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx, 949 bool do_sign, bool do_seal, 950 const char *ccache_name, 951 const char *server, 952 const char *service, 953 const char *username, 954 const char *password, 955 uint32_t add_gss_c_flags, 956 struct gse_context **_gse_ctx) 957 { 958 return NT_STATUS_NOT_IMPLEMENTED; 959 } 960 961 NTSTATUS gse_get_client_auth_token(TALLOC_CTX *mem_ctx, 962 struct gse_context *gse_ctx, 963 DATA_BLOB *token_in, 964 DATA_BLOB *token_out) 965 { 966 return NT_STATUS_NOT_IMPLEMENTED; 967 } 968 969 NTSTATUS gse_init_server(TALLOC_CTX *mem_ctx, 970 bool do_sign, bool do_seal, 971 uint32_t add_gss_c_flags, 972 const char *keytab, 973 struct gse_context **_gse_ctx) 974 { 975 return NT_STATUS_NOT_IMPLEMENTED; 976 } 977 978 NTSTATUS gse_get_server_auth_token(TALLOC_CTX *mem_ctx, 979 struct gse_context *gse_ctx, 980 DATA_BLOB *token_in, 981 DATA_BLOB *token_out) 982 { 983 return NT_STATUS_NOT_IMPLEMENTED; 984 } 985 986 NTSTATUS gse_verify_server_auth_flags(struct gse_context *gse_ctx) 987 { 988 return NT_STATUS_NOT_IMPLEMENTED; 989 } 990 991 bool gse_require_more_processing(struct gse_context *gse_ctx) 992 { 993 return false; 994 } 995 996 DATA_BLOB gse_get_session_key(TALLOC_CTX *mem_ctx, 997 struct gse_context *gse_ctx) 998 { 999 return data_blob_null; 1000 } 1001 1002 NTSTATUS gse_get_client_name(struct gse_context *gse_ctx, 1003 TALLOC_CTX *mem_ctx, char **cli_name) 1004 { 1005 return NT_STATUS_NOT_IMPLEMENTED; 1006 } 1007 1008 NTSTATUS gse_get_authz_data(struct gse_context *gse_ctx, 1009 TALLOC_CTX *mem_ctx, DATA_BLOB *pac) 1010 { 1011 return NT_STATUS_NOT_IMPLEMENTED; 1012 } 1013 1014 NTSTATUS gse_get_pac_blob(struct gse_context *gse_ctx, 1015 TALLOC_CTX *mem_ctx, DATA_BLOB *pac) 1016 { 1017 return NT_STATUS_NOT_IMPLEMENTED; 1018 } 1019 1020 size_t gse_get_signature_length(struct gse_context *gse_ctx, 1021 int seal, size_t payload_size) 1022 { 1023 return 0; 1024 } 1025 1026 NTSTATUS gse_seal(TALLOC_CTX *mem_ctx, struct gse_context *gse_ctx, 1027 DATA_BLOB *data, DATA_BLOB *signature) 1028 { 1029 return NT_STATUS_NOT_IMPLEMENTED; 1030 } 1031 1032 NTSTATUS gse_unseal(TALLOC_CTX *mem_ctx, struct gse_context *gse_ctx, 1033 DATA_BLOB *data, DATA_BLOB *signature) 1034 { 1035 return NT_STATUS_NOT_IMPLEMENTED; 1036 } 1037 1038 NTSTATUS gse_sign(TALLOC_CTX *mem_ctx, struct gse_context *gse_ctx, 1039 DATA_BLOB *data, DATA_BLOB *signature) 1040 { 1041 return NT_STATUS_NOT_IMPLEMENTED; 1042 } 1043 1044 NTSTATUS gse_sigcheck(TALLOC_CTX *mem_ctx, struct gse_context *gse_ctx, 1045 DATA_BLOB *data, DATA_BLOB *signature) 1046 { 1047 return NT_STATUS_NOT_IMPLEMENTED; 1048 } 1049 1050 #endif /* HAVE_KRB5 && HAVE_GSSAPI_EXT_H && HAVE_GSS_WRAP_IOV */ 1098 return max_input_size; 1099 } 1100 1101 /* Find out the maximum output size negotiated on this connection */ 1102 static size_t gensec_gse_max_wrapped_size(struct gensec_security *gensec_security) 1103 { 1104 struct gse_context *gse_ctx = 1105 talloc_get_type_abort(gensec_security->private_data, 1106 struct gse_context); 1107 return gse_ctx->max_wrap_buf_size; 1108 } 1109 1110 static size_t gensec_gse_sig_size(struct gensec_security *gensec_security, 1111 size_t data_size) 1112 { 1113 struct gse_context *gse_ctx = 1114 talloc_get_type_abort(gensec_security->private_data, 1115 struct gse_context); 1116 1117 if (gse_ctx->sig_size > 0) { 1118 return gse_ctx->sig_size; 1119 } 1120 1121 gse_ctx->sig_size = gssapi_get_sig_size(gse_ctx->gssapi_context, 1122 &gse_ctx->gss_mech, 1123 gse_ctx->gss_want_flags, 1124 data_size); 1125 return gse_ctx->sig_size; 1126 } 1127 1128 static const char *gensec_gse_krb5_oids[] = { 1129 GENSEC_OID_KERBEROS5_OLD, 1130 GENSEC_OID_KERBEROS5, 1131 NULL 1132 }; 1133 1134 const struct gensec_security_ops gensec_gse_krb5_security_ops = { 1135 .name = "gse_krb5", 1136 .auth_type = DCERPC_AUTH_TYPE_KRB5, 1137 .oid = gensec_gse_krb5_oids, 1138 .client_start = gensec_gse_client_start, 1139 .server_start = gensec_gse_server_start, 1140 .magic = gensec_magic_check_krb5_oid, 1141 .update = gensec_gse_update, 1142 .session_key = gensec_gse_session_key, 1143 .session_info = gensec_gse_session_info, 1144 .sig_size = gensec_gse_sig_size, 1145 .sign_packet = gensec_gse_sign_packet, 1146 .check_packet = gensec_gse_check_packet, 1147 .seal_packet = gensec_gse_seal_packet, 1148 .unseal_packet = gensec_gse_unseal_packet, 1149 .max_input_size = gensec_gse_max_input_size, 1150 .max_wrapped_size = gensec_gse_max_wrapped_size, 1151 .wrap = gensec_gse_wrap, 1152 .unwrap = gensec_gse_unwrap, 1153 .have_feature = gensec_gse_have_feature, 1154 .expire_time = gensec_gse_expire_time, 1155 .enabled = true, 1156 .kerberos = true, 1157 .priority = GENSEC_GSSAPI 1158 }; 1159 1160 #endif /* HAVE_KRB5 */ -
vendor/current/source3/librpc/crypto/gse.h
r740 r988 22 22 struct gse_context; 23 23 24 #ifndef GSS_C_DCE_STYLE 25 #define GSS_C_DCE_STYLE 0x1000 26 #endif 27 28 NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx, 29 bool do_sign, bool do_seal, 30 const char *ccache_name, 31 const char *server, 32 const char *service, 33 const char *username, 34 const char *password, 35 uint32_t add_gss_c_flags, 36 struct gse_context **_gse_ctx); 37 NTSTATUS gse_get_client_auth_token(TALLOC_CTX *mem_ctx, 38 struct gse_context *gse_ctx, 39 DATA_BLOB *token_in, 40 DATA_BLOB *token_out); 41 42 NTSTATUS gse_init_server(TALLOC_CTX *mem_ctx, 43 bool do_sign, bool do_seal, 44 uint32_t add_gss_c_flags, 45 const char *keytab, 46 struct gse_context **_gse_ctx); 47 NTSTATUS gse_get_server_auth_token(TALLOC_CTX *mem_ctx, 48 struct gse_context *gse_ctx, 49 DATA_BLOB *token_in, 50 DATA_BLOB *token_out); 51 NTSTATUS gse_verify_server_auth_flags(struct gse_context *gse_ctx); 52 53 bool gse_require_more_processing(struct gse_context *gse_ctx); 54 DATA_BLOB gse_get_session_key(TALLOC_CTX *mem_ctx, 55 struct gse_context *gse_ctx); 56 NTSTATUS gse_get_client_name(struct gse_context *gse_ctx, 57 TALLOC_CTX *mem_ctx, char **client_name); 58 NTSTATUS gse_get_authz_data(struct gse_context *gse_ctx, 59 TALLOC_CTX *mem_ctx, DATA_BLOB *pac); 60 NTSTATUS gse_get_pac_blob(struct gse_context *gse_ctx, 61 TALLOC_CTX *mem_ctx, DATA_BLOB *pac); 62 63 size_t gse_get_signature_length(struct gse_context *gse_ctx, 64 int seal, size_t payload_size); 65 NTSTATUS gse_seal(TALLOC_CTX *mem_ctx, struct gse_context *gse_ctx, 66 DATA_BLOB *data, DATA_BLOB *signature); 67 NTSTATUS gse_unseal(TALLOC_CTX *mem_ctx, struct gse_context *gse_ctx, 68 DATA_BLOB *data, DATA_BLOB *signature); 69 NTSTATUS gse_sign(TALLOC_CTX *mem_ctx, struct gse_context *gse_ctx, 70 DATA_BLOB *data, DATA_BLOB *signature); 71 NTSTATUS gse_sigcheck(TALLOC_CTX *mem_ctx, struct gse_context *gse_ctx, 72 DATA_BLOB *data, DATA_BLOB *signature); 24 extern const struct gensec_security_ops gensec_gse_krb5_security_ops; 73 25 74 26 #endif /* _GSE_H_ */ -
vendor/current/source3/librpc/crypto/gse_krb5.c
r740 r988 22 22 #include "secrets.h" 23 23 #include "gse_krb5.h" 24 #include "lib/param/loadparm.h" 24 25 25 26 #ifdef HAVE_KRB5 … … 91 92 int err; 92 93 93 err = asprintf(&host_princ_s, "%s$@%s", global_myname(), lp_realm());94 err = asprintf(&host_princ_s, "%s$@%s", lp_netbios_name(), lp_realm()); 94 95 if (err == -1) { 95 96 return -1; 96 97 } 97 98 98 strlower_m(host_princ_s); 99 if (!strlower_m(host_princ_s)) { 100 SAFE_FREE(host_princ_s); 101 return -1; 102 } 99 103 ret = smb_krb5_parse_name(krbctx, host_princ_s, host_princ); 100 104 if (ret) { … … 170 174 #define CLEARTEXT_PRIV_ENCTYPE -99 171 175 172 static krb5_error_code get_mem_keytab_from_secrets(krb5_context krbctx,173 krb5_keytab *keytab)176 static krb5_error_code fill_mem_keytab_from_secrets(krb5_context krbctx, 177 krb5_keytab *keytab) 174 178 { 175 179 krb5_error_code ret; … … 194 198 } 195 199 pwd_len = strlen(pwd); 196 197 if (*keytab == NULL) {198 /* create memory keytab */199 ret = krb5_kt_resolve(krbctx, SRV_MEM_KEYTAB_NAME, keytab);200 if (ret) {201 DEBUG(1, (__location__ ": Failed to get memory "202 "keytab!\n"));203 return ret;204 }205 }206 200 207 201 ZERO_STRUCT(kt_entry); … … 281 275 } 282 276 283 pwd_old = secrets_fetch_ machine_password(lp_workgroup(), NULL, NULL);277 pwd_old = secrets_fetch_prev_machine_password(lp_workgroup()); 284 278 if (!pwd_old) { 285 279 DEBUG(10, (__location__ ": no prev machine password\n")); … … 332 326 } 333 327 334 if (ret) {335 if (*keytab) {336 krb5_kt_close(krbctx, *keytab);337 *keytab = NULL;338 }339 }340 341 328 return ret; 342 329 } 343 330 344 static krb5_error_code get_mem_keytab_from_system_keytab(krb5_context krbctx, 345 krb5_keytab *keytab, 346 bool verify) 331 static krb5_error_code fill_mem_keytab_from_system_keytab(krb5_context krbctx, 332 krb5_keytab *mkeytab) 347 333 { 348 return KRB5_KT_NOTFOUND; 334 krb5_error_code ret = 0; 335 krb5_keytab keytab = NULL; 336 krb5_kt_cursor kt_cursor; 337 krb5_keytab_entry kt_entry; 338 char *valid_princ_formats[7] = { NULL, NULL, NULL, 339 NULL, NULL, NULL, NULL }; 340 char *entry_princ_s = NULL; 341 fstring my_name, my_fqdn; 342 int i; 343 int err; 344 345 /* Generate the list of principal names which we expect 346 * clients might want to use for authenticating to the file 347 * service. We allow name$,{host,cifs}/{name,fqdn,name.REALM}. */ 348 349 fstrcpy(my_name, lp_netbios_name()); 350 351 my_fqdn[0] = '\0'; 352 name_to_fqdn(my_fqdn, lp_netbios_name()); 353 354 err = asprintf(&valid_princ_formats[0], 355 "%s$@%s", my_name, lp_realm()); 356 if (err == -1) { 357 ret = ENOMEM; 358 goto out; 359 } 360 err = asprintf(&valid_princ_formats[1], 361 "host/%s@%s", my_name, lp_realm()); 362 if (err == -1) { 363 ret = ENOMEM; 364 goto out; 365 } 366 err = asprintf(&valid_princ_formats[2], 367 "host/%s@%s", my_fqdn, lp_realm()); 368 if (err == -1) { 369 ret = ENOMEM; 370 goto out; 371 } 372 err = asprintf(&valid_princ_formats[3], 373 "host/%s.%s@%s", my_name, lp_realm(), lp_realm()); 374 if (err == -1) { 375 ret = ENOMEM; 376 goto out; 377 } 378 err = asprintf(&valid_princ_formats[4], 379 "cifs/%s@%s", my_name, lp_realm()); 380 if (err == -1) { 381 ret = ENOMEM; 382 goto out; 383 } 384 err = asprintf(&valid_princ_formats[5], 385 "cifs/%s@%s", my_fqdn, lp_realm()); 386 if (err == -1) { 387 ret = ENOMEM; 388 goto out; 389 } 390 err = asprintf(&valid_princ_formats[6], 391 "cifs/%s.%s@%s", my_name, lp_realm(), lp_realm()); 392 if (err == -1) { 393 ret = ENOMEM; 394 goto out; 395 } 396 397 ZERO_STRUCT(kt_entry); 398 ZERO_STRUCT(kt_cursor); 399 400 ret = smb_krb5_open_keytab(krbctx, NULL, false, &keytab); 401 if (ret) { 402 DEBUG(1, (__location__ ": smb_krb5_open_keytab failed (%s)\n", 403 error_message(ret))); 404 goto out; 405 } 406 407 /* 408 * Iterate through the keytab. For each key, if the principal 409 * name case-insensitively matches one of the allowed formats, 410 * copy it to the memory keytab. 411 */ 412 413 ret = krb5_kt_start_seq_get(krbctx, keytab, &kt_cursor); 414 if (ret) { 415 DEBUG(1, (__location__ ": krb5_kt_start_seq_get failed (%s)\n", 416 error_message(ret))); 417 goto out; 418 } 419 420 while ((krb5_kt_next_entry(krbctx, keytab, 421 &kt_entry, &kt_cursor) == 0)) { 422 ret = smb_krb5_unparse_name(talloc_tos(), krbctx, 423 kt_entry.principal, 424 &entry_princ_s); 425 if (ret) { 426 DEBUG(1, (__location__ ": smb_krb5_unparse_name " 427 "failed (%s)\n", error_message(ret))); 428 goto out; 429 } 430 431 for (i = 0; i < ARRAY_SIZE(valid_princ_formats); i++) { 432 433 if (!strequal(entry_princ_s, valid_princ_formats[i])) { 434 continue; 435 } 436 437 ret = krb5_kt_add_entry(krbctx, *mkeytab, &kt_entry); 438 if (ret) { 439 DEBUG(1, (__location__ ": smb_krb5_unparse_name " 440 "failed (%s)\n", error_message(ret))); 441 goto out; 442 } 443 } 444 445 /* Free the name we parsed. */ 446 TALLOC_FREE(entry_princ_s); 447 448 /* Free the entry we just read. */ 449 smb_krb5_kt_free_entry(krbctx, &kt_entry); 450 ZERO_STRUCT(kt_entry); 451 } 452 krb5_kt_end_seq_get(krbctx, keytab, &kt_cursor); 453 454 ZERO_STRUCT(kt_cursor); 455 456 out: 457 458 for (i = 0; i < ARRAY_SIZE(valid_princ_formats); i++) { 459 SAFE_FREE(valid_princ_formats[i]); 460 } 461 462 TALLOC_FREE(entry_princ_s); 463 464 { 465 krb5_keytab_entry zero_kt_entry; 466 ZERO_STRUCT(zero_kt_entry); 467 if (memcmp(&zero_kt_entry, &kt_entry, 468 sizeof(krb5_keytab_entry))) { 469 smb_krb5_kt_free_entry(krbctx, &kt_entry); 470 } 471 } 472 473 { 474 krb5_kt_cursor zero_csr; 475 ZERO_STRUCT(zero_csr); 476 if ((memcmp(&kt_cursor, &zero_csr, 477 sizeof(krb5_kt_cursor)) != 0) && keytab) { 478 krb5_kt_end_seq_get(krbctx, keytab, &kt_cursor); 479 } 480 } 481 482 if (keytab) { 483 krb5_kt_close(krbctx, keytab); 484 } 485 486 return ret; 487 } 488 489 static krb5_error_code fill_mem_keytab_from_dedicated_keytab(krb5_context krbctx, 490 krb5_keytab *mkeytab) 491 { 492 krb5_error_code ret = 0; 493 krb5_keytab keytab = NULL; 494 krb5_kt_cursor kt_cursor; 495 krb5_keytab_entry kt_entry; 496 497 ret = smb_krb5_open_keytab(krbctx, lp_dedicated_keytab_file(), 498 false, &keytab); 499 if (ret) { 500 DEBUG(1, (__location__ ": smb_krb5_open_keytab failed (%s)\n", 501 error_message(ret))); 502 return ret; 503 } 504 505 /* 506 * Iterate through the keytab. For each key, if the principal 507 * name case-insensitively matches one of the allowed formats, 508 * copy it to the memory keytab. 509 */ 510 511 ret = krb5_kt_start_seq_get(krbctx, keytab, &kt_cursor); 512 if (ret) { 513 DEBUG(1, (__location__ ": krb5_kt_start_seq_get failed (%s)\n", 514 error_message(ret))); 515 goto out; 516 } 517 518 while ((krb5_kt_next_entry(krbctx, keytab, 519 &kt_entry, &kt_cursor) == 0)) { 520 521 ret = krb5_kt_add_entry(krbctx, *mkeytab, &kt_entry); 522 523 /* Free the entry we just read. */ 524 smb_krb5_kt_free_entry(krbctx, &kt_entry); 525 526 if (ret) { 527 DEBUG(1, (__location__ ": smb_krb5_unparse_name " 528 "failed (%s)\n", error_message(ret))); 529 break; 530 } 531 } 532 krb5_kt_end_seq_get(krbctx, keytab, &kt_cursor); 533 534 out: 535 536 krb5_kt_close(krbctx, keytab); 537 538 return ret; 349 539 } 350 540 … … 352 542 krb5_keytab *keytab) 353 543 { 354 krb5_error_code ret; 544 krb5_error_code ret = 0; 545 krb5_error_code ret1 = 0; 546 krb5_error_code ret2 = 0; 355 547 356 548 *keytab = NULL; 549 550 /* create memory keytab */ 551 ret = krb5_kt_resolve(krbctx, SRV_MEM_KEYTAB_NAME, keytab); 552 if (ret) { 553 DEBUG(1, (__location__ ": Failed to get memory " 554 "keytab!\n")); 555 return ret; 556 } 357 557 358 558 switch (lp_kerberos_method()) { 359 559 default: 360 560 case KERBEROS_VERIFY_SECRETS: 361 ret = get_mem_keytab_from_secrets(krbctx, keytab);561 ret = fill_mem_keytab_from_secrets(krbctx, keytab); 362 562 break; 363 563 case KERBEROS_VERIFY_SYSTEM_KEYTAB: 364 ret = get_mem_keytab_from_system_keytab(krbctx, keytab, true);564 ret = fill_mem_keytab_from_system_keytab(krbctx, keytab); 365 565 break; 366 566 case KERBEROS_VERIFY_DEDICATED_KEYTAB: 367 567 /* just use whatever keytab is configured */ 368 ret = get_mem_keytab_from_system_keytab(krbctx, keytab, false);568 ret = fill_mem_keytab_from_dedicated_keytab(krbctx, keytab); 369 569 break; 370 570 case KERBEROS_VERIFY_SECRETS_AND_KEYTAB: 371 ret = get_mem_keytab_from_secrets(krbctx, keytab);372 if (ret ) {571 ret1 = fill_mem_keytab_from_secrets(krbctx, keytab); 572 if (ret1) { 373 573 DEBUG(3, (__location__ ": Warning! Unable to set mem " 374 574 "keytab from secrets!\n")); 375 575 } 376 576 /* Now append system keytab keys too */ 377 ret = get_mem_keytab_from_system_keytab(krbctx, keytab, true);378 if (ret ) {577 ret2 = fill_mem_keytab_from_system_keytab(krbctx, keytab); 578 if (ret2) { 379 579 DEBUG(3, (__location__ ": Warning! Unable to set mem " 380 "keytab from secrets!\n")); 580 "keytab from system keytab!\n")); 581 } 582 if (ret1 == 0 || ret2 == 0) { 583 ret = 0; 584 } else { 585 ret = ret1; 381 586 } 382 587 break; 588 } 589 590 if (ret) { 591 krb5_kt_close(krbctx, *keytab); 592 *keytab = NULL; 593 DEBUG(1,("%s: Error! Unable to set mem keytab - %d\n", 594 __location__, ret)); 383 595 } 384 596 -
vendor/current/source3/librpc/idl/libnet_join.idl
r740 r988 16 16 typedef enum netr_SchannelType netr_SchannelType; 17 17 18 typedef [public] enum { 19 JoinDomNameTypeUnknown = 0, 20 JoinDomNameTypeDNS = 1, 21 JoinDomNameTypeNBT = 2 22 } libnetjoin_JoinDomNameType; 23 18 24 [nopush,nopull,noopnum] WERROR libnet_JoinCtx( 19 25 [in] string dc_name, 20 26 [in] string machine_name, 21 27 [in,ref] string *domain_name, 28 [in] libnetjoin_JoinDomNameType domain_name_type, 22 29 [in] string account_ou, 23 30 [in] string admin_account, 31 [in] string admin_domain, 24 32 [in,noprint] string admin_password, 25 33 [in] string machine_password, … … 27 35 [in] string os_version, 28 36 [in] string os_name, 37 [in] string os_servicepack, 29 38 [in] boolean8 create_upn, 30 39 [in] string upn, … … 35 44 [in] netr_SchannelType secure_channel_type, 36 45 [in,noprint] messaging_context *msg_ctx, 46 [in] uint32 desired_encryption_types, 37 47 [out] string account_name, 38 48 [out] string netbios_domain_name, … … 43 53 [out] boolean8 modified_config, 44 54 [out] string error_string, 45 [out] boolean8 domain_is_ad 55 [out] boolean8 domain_is_ad, 56 [out] uint32 set_encryption_types 46 57 ); 47 58 … … 52 63 [in] string account_ou, 53 64 [in] string admin_account, 65 [in] string admin_domain, 54 66 [in,noprint] string admin_password, 55 67 [in] string machine_password, -
vendor/current/source3/librpc/idl/libnetapi.idl
r740 r988 778 778 779 779 /*******************************************/ 780 /* NetWkstaGetInfo */ 781 /*******************************************/ 782 783 [public] typedef struct { 784 uint32 wki100_platform_id; 785 string wki100_computername; 786 string wki100_langroup; 787 uint32 wki100_ver_major; 788 uint32 wki100_ver_minor; 789 } WKSTA_INFO_100; 790 791 [public] typedef struct { 792 uint32 wki101_platform_id; 793 string wki101_computername; 794 string wki101_langroup; 795 uint32 wki101_ver_major; 796 uint32 wki101_ver_minor; 797 string wki101_lanroot; 798 } WKSTA_INFO_101; 799 800 [public] typedef struct { 801 uint32 wki102_platform_id; 802 string wki102_computername; 803 string wki102_langroup; 804 uint32 wki102_ver_major; 805 uint32 wki102_ver_minor; 806 string wki102_lanroot; 807 uint32 wki102_logged_on_users; 808 } WKSTA_INFO_102; 809 810 [nopush,nopull] NET_API_STATUS NetWkstaGetInfo( 811 [in,unique] string *server_name, 812 [in] uint32 level, 813 [out] uint8 **buffer 814 ); 815 816 /*******************************************/ 780 817 /* NetGetDCName */ 781 818 /*******************************************/ … … 801 838 /*******************************************/ 802 839 803 [public] typedef [ v1_enum] enum{840 [public] typedef [bitmap32bit] bitmap { 804 841 DS_PDC_FLAG = 0x00000001, 805 842 DS_GC_FLAG = 0x00000004, … … 814 851 DS_SELECT_SECRET_DOMAIN_6_FLAG = 0x00000800, 815 852 DS_FULL_SECRET_DOMAIN_6_FLAG = 0x00001000, 853 DS_WS_FLAG = 0x00002000, 854 DS_DS_8_FLAG = 0x00004000, 816 855 DS_DNS_CONTROLLER_FLAG = 0x20000000, 817 856 DS_DNS_DOMAIN_FLAG = 0x40000000, … … 1743 1782 1744 1783 typedef struct { 1784 string shi502_netname; 1785 uint32 shi502_type; 1786 string shi502_remark; 1787 uint32 shi502_permissions; 1788 uint32 shi502_max_uses; 1789 uint32 shi502_current_uses; 1790 string shi502_path; 1791 string shi502_passwd; 1792 uint32 shi502_reserved; 1793 security_descriptor *shi502_security_descriptor; 1794 } SHARE_INFO_502; 1795 1796 typedef struct { 1745 1797 string shi1004_remark; 1746 1798 } SHARE_INFO_1004; -
vendor/current/source3/librpc/idl/perfcount.idl
r414 r988 157 157 uint32 Padding; 158 158 /* Now when I'm marshalling this, I'll need to call prs_align_uint64() 159 before I start encodin tthe uint64 structs */159 before I start encoding the uint64 structs */ 160 160 /* clock rate * seconds uptime */ 161 161 hyper PerfTime; -
vendor/current/source3/librpc/idl/secrets.idl
r740 r988 26 26 } TRUSTED_DOM_PASS; 27 27 28 /* 29 * s3 on-disc storage structure for lsa secrets, do not change ! 30 */ 31 32 typedef [public] struct { 33 DATA_BLOB *secret_current; 34 NTTIME secret_current_lastchange; 35 DATA_BLOB *secret_old; 36 NTTIME secret_old_lastchange; 37 security_descriptor *sd; 38 } lsa_secret; 39 28 40 } 29 41 -
vendor/current/source3/librpc/idl/wscript_build
r740 r988 6 6 7 7 bld.SAMBA_PIDL_LIST('PIDL', 8 '''messaging.idl libnetapi.idl notify.idl 9 perfcount.idl secrets.idl libnet_join.idl server_id.idl''', 8 '''libnetapi.idl open_files.idl 9 perfcount.idl secrets.idl libnet_join.idl 10 smbXsrv.idl 11 leases_db.idl 12 ''', 10 13 options='--includedir=%s --header --ndr-parser' % topinclude, 11 14 output_dir='../gen_ndr') 12 13 bld.SAMBA_PIDL_LIST('PIDL',14 'wbint.idl',15 options='--includedir=%s --header --ndr-parser --samba3-ndr-server --client' % topinclude,16 output_dir='../gen_ndr') -
vendor/current/source3/librpc/rpc/dcerpc.h
r919 r988 34 34 35 35 struct NL_AUTH_MESSAGE; 36 struct gensec_security; 36 37 37 38 /* auth state for all bind types. */ … … 40 41 enum dcerpc_AuthType auth_type; 41 42 enum dcerpc_AuthLevel auth_level; 43 uint32_t auth_context_id; 44 bool client_hdr_signing; 45 bool hdr_signing; 42 46 bool verified_bitmask1; 43 47 44 void *auth_ctx; 45 uint32_t auth_context_id; 48 struct gensec_security *auth_ctx; 46 49 47 /* Only the client code uses these 3 for now */ 48 char *domain; 49 char *user_name; 50 DATA_BLOB user_session_key; 50 /* Only the client code uses this for now */ 51 DATA_BLOB transport_session_key; 51 52 }; 52 53 … … 63 64 struct ncacn_packet *r, 64 65 bool bigendian); 65 NTSTATUS dcerpc_push_schannel_bind(TALLOC_CTX *mem_ctx,66 struct NL_AUTH_MESSAGE *r,67 DATA_BLOB *blob);68 66 NTSTATUS dcerpc_push_dcerpc_auth(TALLOC_CTX *mem_ctx, 69 67 enum dcerpc_AuthType auth_type, … … 75 73 NTSTATUS dcerpc_guess_sizes(struct pipe_auth_data *auth, 76 74 size_t header_len, size_t data_left, 77 size_t max_xmit_frag, size_t pad_alignment,75 size_t max_xmit_frag, 78 76 size_t *data_to_send, size_t *frag_len, 79 77 size_t *auth_len, size_t *pad_len); … … 86 84 DATA_BLOB *raw_pkt); 87 85 88 /* The following definitions come from librpc/rpc/rpc_common.c */89 90 bool smb_register_ndr_interface(const struct ndr_interface_table *interface);91 const struct ndr_interface_table *get_iface_from_syntax(92 const struct ndr_syntax_id *syntax);93 const char *get_pipe_name_from_syntax(TALLOC_CTX *mem_ctx,94 const struct ndr_syntax_id *syntax);95 96 86 #endif /* __S3_DCERPC_H__ */ -
vendor/current/source3/librpc/rpc/dcerpc_ep.c
r917 r988 2 2 * Endpoint Mapper Functions 3 3 * DCERPC local endpoint mapper client routines 4 * Copyright (c) 2010 4 * Copyright (c) 2010-2011 Andreas Schneider. 5 5 * 6 6 * This program is free software; you can redistribute it and/or modify … … 25 25 #include "auth.h" 26 26 #include "rpc_server/rpc_ncacn_np.h" 27 #include "../lib/tsocket/tsocket.h" 28 #include "rpc_server/rpc_config.h" 27 29 28 30 #define EPM_MAX_ANNOTATION_SIZE 64 29 31 30 NTSTATUS dcerpc_binding_vector_create(TALLOC_CTX *mem_ctx, 31 const struct ndr_interface_table *iface, 32 uint16_t port, 33 const char *ncalrpc, 34 struct dcerpc_binding_vector **pbvec) 32 struct dcerpc_binding_vector { 33 struct dcerpc_binding **bindings; 34 uint32_t count; 35 uint32_t allocated; 36 }; 37 38 static bool binding_vector_realloc(struct dcerpc_binding_vector *bvec) 39 { 40 if (bvec->count >= bvec->allocated) { 41 struct dcerpc_binding **tmp; 42 43 tmp = talloc_realloc(bvec, 44 bvec->bindings, 45 struct dcerpc_binding *, 46 bvec->allocated * 2); 47 if (tmp == NULL) { 48 return false; 49 } 50 bvec->bindings = tmp; 51 bvec->allocated = bvec->allocated * 2; 52 } 53 54 return true; 55 } 56 57 NTSTATUS dcerpc_binding_vector_new(TALLOC_CTX *mem_ctx, 58 struct dcerpc_binding_vector **pbvec) 35 59 { 36 60 struct dcerpc_binding_vector *bvec; 37 uint32_t ep_count;38 uint32_t count = 0;39 uint32_t i;40 61 NTSTATUS status; 41 62 TALLOC_CTX *tmp_ctx; … … 45 66 return NT_STATUS_NO_MEMORY; 46 67 } 47 48 ep_count = iface->endpoints->count;49 68 50 69 bvec = talloc_zero(tmp_ctx, struct dcerpc_binding_vector); … … 54 73 } 55 74 56 bvec->bindings = talloc_zero_array(bvec, struct dcerpc_binding, ep_count); 75 bvec->bindings = talloc_zero_array(bvec, 76 struct dcerpc_binding *, 77 4); 57 78 if (bvec->bindings == NULL) { 58 79 status = NT_STATUS_NO_MEMORY; … … 60 81 } 61 82 62 for (i = 0; i < ep_count; i++) { 63 struct dcerpc_binding *b; 64 65 b = talloc_zero(bvec->bindings, struct dcerpc_binding); 66 if (b == NULL) { 67 status = NT_STATUS_NO_MEMORY; 68 goto done; 69 } 70 71 status = dcerpc_parse_binding(b, iface->endpoints->names[i], &b); 72 if (!NT_STATUS_IS_OK(status)) { 73 status = NT_STATUS_UNSUCCESSFUL; 74 goto done; 75 } 76 77 b->object = iface->syntax_id; 78 79 switch (b->transport) { 80 case NCACN_NP: 81 b->host = talloc_asprintf(b, "\\\\%s", global_myname()); 82 if (b->host == NULL) { 83 status = NT_STATUS_NO_MEMORY; 84 goto done; 85 } 86 break; 87 case NCACN_IP_TCP: 88 if (port == 0) { 89 talloc_free(b); 90 continue; 91 } 92 93 b->endpoint = talloc_asprintf(b, "%u", port); 94 if (b->endpoint == NULL) { 95 status = NT_STATUS_NO_MEMORY; 96 goto done; 97 } 98 99 break; 100 case NCALRPC: 101 if (ncalrpc == NULL) { 102 talloc_free(b); 103 continue; 104 } 105 106 b->endpoint = talloc_asprintf(b, 107 "%s/%s", 108 lp_ncalrpc_dir(), 109 ncalrpc); 110 if (b->endpoint == NULL) { 111 status = NT_STATUS_NO_MEMORY; 112 goto done; 113 } 114 break; 115 default: 116 talloc_free(b); 117 continue; 118 } 119 120 bvec->bindings[count] = *b; 121 count++; 122 } 123 124 bvec->count = count; 83 bvec->allocated = 4; 84 bvec->count = 0; 125 85 126 86 *pbvec = talloc_move(mem_ctx, &bvec); … … 133 93 } 134 94 95 NTSTATUS dcerpc_binding_vector_add_np_default(const struct ndr_interface_table *iface, 96 struct dcerpc_binding_vector *bvec) 97 { 98 uint32_t ep_count = iface->endpoints->count; 99 uint32_t i; 100 NTSTATUS status; 101 bool ok; 102 103 for (i = 0; i < ep_count; i++) { 104 struct dcerpc_binding *b; 105 enum dcerpc_transport_t transport; 106 char *unc = NULL; 107 108 status = dcerpc_parse_binding(bvec->bindings, 109 iface->endpoints->names[i], 110 &b); 111 if (!NT_STATUS_IS_OK(status)) { 112 return NT_STATUS_UNSUCCESSFUL; 113 } 114 115 /* Only add the named pipes defined in the iface endpoints */ 116 transport = dcerpc_binding_get_transport(b); 117 if (transport != NCACN_NP) { 118 talloc_free(b); 119 continue; 120 } 121 122 status = dcerpc_binding_set_abstract_syntax(b, &iface->syntax_id); 123 if (!NT_STATUS_IS_OK(status)) { 124 talloc_free(b); 125 return NT_STATUS_UNSUCCESSFUL; 126 } 127 128 unc = talloc_asprintf(b, "\\\\%s", lp_netbios_name()); 129 if (unc == NULL) { 130 talloc_free(b); 131 return NT_STATUS_NO_MEMORY; 132 } 133 134 status = dcerpc_binding_set_string_option(b, "host", unc); 135 TALLOC_FREE(unc); 136 if (!NT_STATUS_IS_OK(status)) { 137 talloc_free(b); 138 return NT_STATUS_NO_MEMORY; 139 } 140 141 ok = binding_vector_realloc(bvec); 142 if (!ok) { 143 talloc_free(b); 144 return NT_STATUS_NO_MEMORY; 145 } 146 147 bvec->bindings[bvec->count] = b; 148 bvec->count++; 149 } 150 151 return NT_STATUS_OK; 152 } 153 154 NTSTATUS dcerpc_binding_vector_add_port(const struct ndr_interface_table *iface, 155 struct dcerpc_binding_vector *bvec, 156 const char *host, 157 uint16_t _port) 158 { 159 uint32_t ep_count = iface->endpoints->count; 160 uint32_t i; 161 NTSTATUS status; 162 bool ok; 163 char port[6]; 164 165 snprintf(port, sizeof(port), "%u", _port); 166 167 for (i = 0; i < ep_count; i++) { 168 struct dcerpc_binding *b; 169 enum dcerpc_transport_t transport; 170 171 status = dcerpc_parse_binding(bvec->bindings, 172 iface->endpoints->names[i], 173 &b); 174 if (!NT_STATUS_IS_OK(status)) { 175 return NT_STATUS_UNSUCCESSFUL; 176 } 177 178 transport = dcerpc_binding_get_transport(b); 179 if (transport != NCACN_IP_TCP) { 180 talloc_free(b); 181 continue; 182 } 183 184 status = dcerpc_binding_set_abstract_syntax(b, &iface->syntax_id); 185 if (!NT_STATUS_IS_OK(status)) { 186 talloc_free(b); 187 return NT_STATUS_UNSUCCESSFUL; 188 } 189 190 status = dcerpc_binding_set_string_option(b, "host", host); 191 if (!NT_STATUS_IS_OK(status)) { 192 talloc_free(b); 193 return NT_STATUS_UNSUCCESSFUL; 194 } 195 196 status = dcerpc_binding_set_string_option(b, "endpoint", port); 197 if (!NT_STATUS_IS_OK(status)) { 198 talloc_free(b); 199 return NT_STATUS_UNSUCCESSFUL; 200 } 201 202 ok = binding_vector_realloc(bvec); 203 if (!ok) { 204 talloc_free(b); 205 return NT_STATUS_NO_MEMORY; 206 } 207 208 bvec->bindings[bvec->count] = b; 209 bvec->count++; 210 211 break; 212 } 213 214 return NT_STATUS_OK; 215 } 216 217 NTSTATUS dcerpc_binding_vector_add_unix(const struct ndr_interface_table *iface, 218 struct dcerpc_binding_vector *bvec, 219 const char *name) 220 { 221 uint32_t ep_count = iface->endpoints->count; 222 uint32_t i; 223 NTSTATUS status; 224 bool ok; 225 226 for (i = 0; i < ep_count; i++) { 227 struct dcerpc_binding *b; 228 enum dcerpc_transport_t transport; 229 char *endpoint = NULL; 230 231 status = dcerpc_parse_binding(bvec->bindings, 232 iface->endpoints->names[i], 233 &b); 234 if (!NT_STATUS_IS_OK(status)) { 235 return NT_STATUS_UNSUCCESSFUL; 236 } 237 238 transport = dcerpc_binding_get_transport(b); 239 if (transport != NCALRPC) { 240 talloc_free(b); 241 continue; 242 } 243 244 status = dcerpc_binding_set_abstract_syntax(b, &iface->syntax_id); 245 if (!NT_STATUS_IS_OK(status)) { 246 talloc_free(b); 247 return NT_STATUS_UNSUCCESSFUL; 248 } 249 250 endpoint = talloc_asprintf(b, 251 "%s/%s", 252 lp_ncalrpc_dir(), 253 name); 254 if (endpoint == NULL) { 255 talloc_free(b); 256 return NT_STATUS_NO_MEMORY; 257 } 258 259 status = dcerpc_binding_set_string_option(b, "endpoint", endpoint); 260 TALLOC_FREE(endpoint); 261 if (!NT_STATUS_IS_OK(status)) { 262 talloc_free(b); 263 return NT_STATUS_UNSUCCESSFUL; 264 } 265 266 ok = binding_vector_realloc(bvec); 267 if (!ok) { 268 talloc_free(b); 269 return NT_STATUS_NO_MEMORY; 270 } 271 272 bvec->bindings[bvec->count] = b; 273 bvec->count++; 274 275 break; 276 } 277 278 return NT_STATUS_OK; 279 } 280 281 NTSTATUS dcerpc_binding_vector_replace_iface(const struct ndr_interface_table *iface, 282 struct dcerpc_binding_vector *v) 283 { 284 uint32_t i; 285 286 for (i = 0; i < v->count; i++) { 287 struct dcerpc_binding *b = v->bindings[i]; 288 NTSTATUS status; 289 290 status = dcerpc_binding_set_abstract_syntax(b, 291 &iface->syntax_id); 292 if (!NT_STATUS_IS_OK(status)) { 293 return status; 294 } 295 } 296 297 return NT_STATUS_OK; 298 } 299 300 struct dcerpc_binding_vector *dcerpc_binding_vector_dup(TALLOC_CTX *mem_ctx, 301 const struct dcerpc_binding_vector *bvec) 302 { 303 struct dcerpc_binding_vector *v; 304 uint32_t i; 305 306 v = talloc(mem_ctx, struct dcerpc_binding_vector); 307 if (v == NULL) { 308 return NULL; 309 } 310 311 v->bindings = talloc_array(v, struct dcerpc_binding *, bvec->allocated); 312 if (v->bindings == NULL) { 313 talloc_free(v); 314 return NULL; 315 } 316 v->allocated = bvec->allocated; 317 318 for (i = 0; i < bvec->count; i++) { 319 struct dcerpc_binding *b; 320 321 b = dcerpc_binding_dup(v->bindings, bvec->bindings[i]); 322 if (b == NULL) { 323 talloc_free(v); 324 return NULL; 325 } 326 v->bindings[i] = b; 327 } 328 v->count = bvec->count; 329 330 return v; 331 } 332 135 333 static NTSTATUS ep_register(TALLOC_CTX *mem_ctx, 334 struct messaging_context *msg_ctx, 136 335 const struct ndr_interface_table *iface, 137 336 const struct dcerpc_binding_vector *bind_vec, … … 146 345 struct pipe_auth_data *auth; 147 346 const char *ncalrpc_sock; 148 const char *rpcsrv_type;347 enum rpc_service_mode_e epmd_mode; 149 348 struct epm_entry_t *entries; 150 349 uint32_t num_ents, i; … … 166 365 } 167 366 168 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM, 169 "rpc_server", "epmapper", 170 "none"); 171 172 if (StrCaseCmp(rpcsrv_type, "embedded") == 0) { 173 static struct client_address client_id; 174 175 strlcpy(client_id.addr, "localhost", sizeof(client_id.addr)); 176 client_id.name = "localhost"; 367 epmd_mode = rpc_epmapper_mode(); 368 369 if (epmd_mode == RPC_SERVICE_MODE_EMBEDDED) { 370 struct tsocket_address *local; 371 int rc; 372 373 rc = tsocket_address_inet_from_strings(tmp_ctx, 374 "ip", 375 "127.0.0.1", 376 0, 377 &local); 378 if (rc < 0) { 379 return NT_STATUS_NO_MEMORY; 380 } 177 381 178 382 status = rpcint_binding_handle(tmp_ctx, 179 383 &ndr_table_epmapper, 180 &client_id,384 local, 181 385 get_session_info_system(), 182 server_messaging_context(),386 msg_ctx, 183 387 &h); 184 388 if (!NT_STATUS_IS_OK(status)) { … … 187 391 goto done; 188 392 } 189 } else if ( StrCaseCmp(rpcsrv_type, "daemon") == 0) {393 } else if (epmd_mode == RPC_SERVICE_MODE_EXTERNAL) { 190 394 /* Connect to the endpoint mapper locally */ 191 395 ncalrpc_sock = talloc_asprintf(tmp_ctx, … … 200 404 status = rpc_pipe_open_ncalrpc(tmp_ctx, 201 405 ncalrpc_sock, 202 &ndr_table_epmapper .syntax_id,406 &ndr_table_epmapper, 203 407 &cli); 204 408 if (!NT_STATUS_IS_OK(status)) { … … 228 432 229 433 for (i = 0; i < num_ents; i++) { 230 struct dcerpc_binding *map_binding = &bind_vec->bindings[i];434 struct dcerpc_binding *map_binding; 231 435 struct epm_twr_t *map_tower; 436 437 map_binding = dcerpc_binding_dup(entries, bind_vec->bindings[i]); 438 if (map_binding == NULL) { 439 status = NT_STATUS_NO_MEMORY; 440 goto done; 441 } 442 443 status = dcerpc_binding_set_abstract_syntax(map_binding, 444 &iface->syntax_id); 445 if (!NT_STATUS_IS_OK(status)) { 446 goto done; 447 } 232 448 233 449 map_tower = talloc_zero(entries, struct epm_twr_t); … … 243 459 goto done; 244 460 } 461 462 TALLOC_FREE(map_binding); 245 463 246 464 entries[i].tower = map_tower; … … 260 478 entries[i].object = *object_guid; 261 479 } else { 262 entries[i].object = map_binding->object.uuid;480 ZERO_STRUCT(entries[i].object); 263 481 } 264 482 } … … 302 520 303 521 NTSTATUS dcerpc_ep_register(TALLOC_CTX *mem_ctx, 522 struct messaging_context *msg_ctx, 304 523 const struct ndr_interface_table *iface, 305 524 const struct dcerpc_binding_vector *bind_vec, … … 309 528 { 310 529 return ep_register(mem_ctx, 530 msg_ctx, 311 531 iface, 312 532 bind_vec, … … 319 539 320 540 NTSTATUS dcerpc_ep_register_noreplace(TALLOC_CTX *mem_ctx, 541 struct messaging_context *msg_ctx, 321 542 const struct ndr_interface_table *iface, 322 543 const struct dcerpc_binding_vector *bind_vec, … … 326 547 { 327 548 return ep_register(mem_ctx, 549 msg_ctx, 328 550 iface, 329 551 bind_vec, … … 335 557 } 336 558 337 NTSTATUS dcerpc_ep_unregister(const struct ndr_interface_table *iface, 559 NTSTATUS dcerpc_ep_unregister(struct messaging_context *msg_ctx, 560 const struct ndr_interface_table *iface, 338 561 const struct dcerpc_binding_vector *bind_vec, 339 562 const struct GUID *object_guid) 340 563 { 341 564 return ep_register(NULL, 565 msg_ctx, 342 566 iface, 343 567 bind_vec, -
vendor/current/source3/librpc/rpc/dcerpc_ep.h
r740 r988 2 2 * Endpoint Mapper Functions 3 3 * DCERPC local endpoint mapper client routines 4 * Copyright (c) 2010 4 * Copyright (c) 2010-2011 Andreas Schneider. 5 5 * 6 6 * This program is free software; you can redistribute it and/or modify … … 21 21 #define _DCERPC_EP_H_ 22 22 23 struct dcerpc_binding_vector { 24 struct dcerpc_binding *bindings; 25 uint32_t count; 26 }; 23 struct dcerpc_binding_vector; 27 24 28 NTSTATUS dcerpc_binding_vector_create(TALLOC_CTX *mem_ctx, 29 const struct ndr_interface_table *iface, 30 uint16_t port, 31 const char *ncalrpc, 32 struct dcerpc_binding_vector **pbvec); 25 /** 26 * @brief Allocate a new binding vector. 27 * 28 * @param[in] mem_ctx The memory context to allocate the vector. 29 * 30 * @param[out] pbvec A pointer to store the binding vector. 31 * 32 * @return An NTSTATUS error code. 33 */ 34 NTSTATUS dcerpc_binding_vector_new(TALLOC_CTX *mem_ctx, 35 struct dcerpc_binding_vector **pbvec); 36 37 /** 38 * @brief Add default named pipes to the binding vector. 39 * 40 * @param[in] iface The rpc interface to add. 41 * 42 * @param[in] bvec The binding vector to add the interface. 43 * 44 * @return An NTSTATUS error code. 45 */ 46 NTSTATUS dcerpc_binding_vector_add_np_default(const struct ndr_interface_table *iface, 47 struct dcerpc_binding_vector *bvec); 48 49 /** 50 * @brief Add a tcpip port to a binding vector. 51 * 52 * @param[in] iface The rpc interface to add. 53 * 54 * @param[in] bvec The binding vector to add the interface, host and port. 55 * 56 * @param[in] host The ip address of the network interface bound. 57 * 58 * @param[in] port The port bound. 59 * 60 * @return An NTSTATUS error code. 61 */ 62 NTSTATUS dcerpc_binding_vector_add_port(const struct ndr_interface_table *iface, 63 struct dcerpc_binding_vector *bvec, 64 const char *host, 65 uint16_t port); 66 67 /** 68 * @brief Add a unix socket (ncalrpc) to a binding vector. 69 * 70 * @param[in] iface The rpc interface to add. 71 * 72 * @param[in] bvec The binding vector to add the interface, host and port. 73 * 74 * @param[in] name The name of the unix socket. 75 * 76 * @return An NTSTATUS error code. 77 */ 78 NTSTATUS dcerpc_binding_vector_add_unix(const struct ndr_interface_table *iface, 79 struct dcerpc_binding_vector *bvec, 80 const char *name); 81 82 /** 83 * @brief Duplicate a dcerpc_binding_vector. 84 * 85 * @param[in] mem_ctx The memory context to create the duplicate on. 86 * 87 * @param[in] bvec The binding vector to duplicate. 88 * 89 * @return The duplicated binding vector or NULL on error. 90 */ 91 struct dcerpc_binding_vector *dcerpc_binding_vector_dup(TALLOC_CTX *mem_ctx, 92 const struct dcerpc_binding_vector *bvec); 93 94 /** 95 * @brief Replace the interface of the bindings in the vector. 96 * 97 * @param[in] iface The new interface identifier to use. 98 * 99 * @param[in] v The binding vector to change. 100 * 101 * @return An NTSTATUS error code. 102 */ 103 NTSTATUS dcerpc_binding_vector_replace_iface(const struct ndr_interface_table *iface, 104 struct dcerpc_binding_vector *v); 33 105 34 106 /** … … 65 137 */ 66 138 NTSTATUS dcerpc_ep_register(TALLOC_CTX *mem_ctx, 139 struct messaging_context *msg_ctx, 67 140 const struct ndr_interface_table *iface, 68 141 const struct dcerpc_binding_vector *bind_vec, … … 72 145 73 146 NTSTATUS dcerpc_ep_register_noreplace(TALLOC_CTX *mem_ctx, 147 struct messaging_context *msg_ctx, 74 148 const struct ndr_interface_table *iface, 75 149 const struct dcerpc_binding_vector *bind_vec, … … 78 152 struct dcerpc_binding_handle **ph); 79 153 80 NTSTATUS dcerpc_ep_unregister(const struct ndr_interface_table *iface, 154 NTSTATUS dcerpc_ep_unregister(struct messaging_context *msg_ctx, 155 const struct ndr_interface_table *iface, 81 156 const struct dcerpc_binding_vector *bind_vec, 82 157 const struct GUID *object_guid); -
vendor/current/source3/librpc/rpc/dcerpc_helpers.c
r919 r988 22 22 #include "librpc/rpc/dcerpc.h" 23 23 #include "librpc/gen_ndr/ndr_dcerpc.h" 24 #include "librpc/gen_ndr/ndr_schannel.h"25 #include "../libcli/auth/schannel.h"26 #include "../libcli/auth/spnego.h"27 #include "../libcli/auth/ntlmssp.h"28 #include "ntlmssp_wrap.h"29 24 #include "librpc/crypto/gse.h" 30 #include " librpc/crypto/spnego.h"25 #include "auth/gensec/gensec.h" 31 26 32 27 #undef DBGC_CLASS … … 138 133 139 134 /** 140 * @brief NDR Encodes a NL_AUTH_MESSAGE141 *142 * @param mem_ctx The memory context the blob will be allocated on143 * @param r The NL_AUTH_MESSAGE to encode144 * @param blob [out] The encoded blob if successful145 *146 * @return a NTSTATUS error code147 */148 NTSTATUS dcerpc_push_schannel_bind(TALLOC_CTX *mem_ctx,149 struct NL_AUTH_MESSAGE *r,150 DATA_BLOB *blob)151 {152 enum ndr_err_code ndr_err;153 154 ndr_err = ndr_push_struct_blob(blob, mem_ctx, r,155 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);156 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {157 return ndr_map_error2ntstatus(ndr_err);158 }159 160 if (DEBUGLEVEL >= 10) {161 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, r);162 }163 164 return NT_STATUS_OK;165 }166 167 /**168 135 * @brief NDR Encodes a dcerpc_auth structure 169 136 * … … 218 185 * @param data_left The data left in the send buffer 219 186 * @param max_xmit_frag The max fragment size. 220 * @param pad_alignment The NDR padding size.221 187 * @param data_to_send [out] The max data we will send in the pdu 222 188 * @param frag_len [out] The total length of the fragment … … 228 194 NTSTATUS dcerpc_guess_sizes(struct pipe_auth_data *auth, 229 195 size_t header_len, size_t data_left, 230 size_t max_xmit_frag, size_t pad_alignment,196 size_t max_xmit_frag, 231 197 size_t *data_to_send, size_t *frag_len, 232 198 size_t *auth_len, size_t *pad_len) … … 234 200 size_t max_len; 235 201 size_t mod_len; 236 struct schannel_state *schannel_auth; 237 struct spnego_context *spnego_ctx; 238 struct gse_context *gse_ctx; 239 enum spnego_mech auth_type; 240 void *auth_ctx; 241 bool seal = false; 242 NTSTATUS status; 202 struct gensec_security *gensec_security; 243 203 244 204 /* no auth token cases first */ … … 255 215 256 216 case DCERPC_AUTH_LEVEL_PRIVACY: 257 seal = true;258 217 break; 259 218 … … 273 232 switch (auth->auth_type) { 274 233 case DCERPC_AUTH_TYPE_SPNEGO: 275 spnego_ctx = talloc_get_type_abort(auth->auth_ctx,276 struct spnego_context);277 status = spnego_get_negotiated_mech(spnego_ctx,278 &auth_type, &auth_ctx);279 if (!NT_STATUS_IS_OK(status)) {280 return status;281 }282 switch (auth_type) {283 case SPNEGO_NTLMSSP:284 *auth_len = NTLMSSP_SIG_SIZE;285 break;286 287 case SPNEGO_KRB5:288 gse_ctx = talloc_get_type_abort(auth_ctx,289 struct gse_context);290 if (!gse_ctx) {291 return NT_STATUS_INVALID_PARAMETER;292 }293 *auth_len = gse_get_signature_length(gse_ctx,294 seal, max_len);295 break;296 297 default:298 return NT_STATUS_INVALID_PARAMETER;299 }300 break;301 302 234 case DCERPC_AUTH_TYPE_NTLMSSP: 303 *auth_len = NTLMSSP_SIG_SIZE; 304 break; 305 235 case DCERPC_AUTH_TYPE_KRB5: 306 236 case DCERPC_AUTH_TYPE_SCHANNEL: 307 schannel_auth = talloc_get_type_abort(auth->auth_ctx, 308 struct schannel_state); 309 *auth_len = netsec_outgoing_sig_size(schannel_auth); 310 break; 311 312 case DCERPC_AUTH_TYPE_KRB5: 313 gse_ctx = talloc_get_type_abort(auth->auth_ctx, 314 struct gse_context); 315 *auth_len = gse_get_signature_length(gse_ctx, 316 seal, max_len); 317 break; 318 237 gensec_security = auth->auth_ctx; 238 mod_len = (max_len % DCERPC_AUTH_PAD_ALIGNMENT); 239 *auth_len = gensec_sig_size(gensec_security, max_len - mod_len); 240 if (*auth_len == 0) { 241 return NT_STATUS_INTERNAL_ERROR; 242 } 243 break; 319 244 default: 320 245 return NT_STATUS_INVALID_PARAMETER; … … 322 247 323 248 max_len -= *auth_len; 249 mod_len = (max_len % DCERPC_AUTH_PAD_ALIGNMENT); 250 max_len -= mod_len; 324 251 325 252 *data_to_send = MIN(max_len, data_left); 326 253 327 mod_len = (header_len + *data_to_send) % pad_alignment; 328 if (mod_len) { 329 *pad_len = pad_alignment - mod_len; 330 } else { 331 *pad_len = 0; 332 } 333 334 if (*data_to_send + *pad_len > max_len) { 335 *data_to_send -= pad_alignment; 336 } 254 *pad_len = DCERPC_AUTH_PAD_LENGTH(*data_to_send); 337 255 338 256 *frag_len = header_len + *data_to_send + *pad_len … … 346 264 ********************************************************************/ 347 265 348 static NTSTATUS add_ ntlmssp_auth_footer(struct auth_ntlmssp_state *auth_state,266 static NTSTATUS add_generic_auth_footer(struct gensec_security *gensec_security, 349 267 enum dcerpc_AuthLevel auth_level, 350 268 DATA_BLOB *rpc_out) … … 356 274 NTSTATUS status; 357 275 358 if (! auth_state) {276 if (!gensec_security) { 359 277 return NT_STATUS_INVALID_PARAMETER; 360 278 } … … 363 281 case DCERPC_AUTH_LEVEL_PRIVACY: 364 282 /* Data portion is encrypted. */ 365 status = auth_ntlmssp_seal_packet(auth_state,366 367 368 369 370 371 372 283 status = gensec_seal_packet(gensec_security, 284 rpc_out->data, 285 rpc_out->data 286 + DCERPC_RESPONSE_LENGTH, 287 data_and_pad_len, 288 rpc_out->data, 289 rpc_out->length, 290 &auth_blob); 373 291 if (!NT_STATUS_IS_OK(status)) { 374 292 return status; … … 378 296 case DCERPC_AUTH_LEVEL_INTEGRITY: 379 297 /* Data is signed. */ 380 status = auth_ntlmssp_sign_packet(auth_state,381 382 383 384 385 386 387 298 status = gensec_sign_packet(gensec_security, 299 rpc_out->data, 300 rpc_out->data 301 + DCERPC_RESPONSE_LENGTH, 302 data_and_pad_len, 303 rpc_out->data, 304 rpc_out->length, 305 &auth_blob); 388 306 if (!NT_STATUS_IS_OK(status)) { 389 307 return status; … … 414 332 ********************************************************************/ 415 333 416 static NTSTATUS get_ ntlmssp_auth_footer(struct auth_ntlmssp_state *auth_state,334 static NTSTATUS get_generic_auth_footer(struct gensec_security *gensec_security, 417 335 enum dcerpc_AuthLevel auth_level, 418 336 DATA_BLOB *data, DATA_BLOB *full_pkt, 419 337 DATA_BLOB *auth_token) 420 338 { 339 if (gensec_security == NULL) { 340 return NT_STATUS_INVALID_PARAMETER; 341 } 342 421 343 switch (auth_level) { 422 344 case DCERPC_AUTH_LEVEL_PRIVACY: 423 345 /* Data portion is encrypted. */ 424 return auth_ntlmssp_unseal_packet(auth_state,425 426 427 428 429 346 return gensec_unseal_packet(gensec_security, 347 data->data, 348 data->length, 349 full_pkt->data, 350 full_pkt->length, 351 auth_token); 430 352 431 353 case DCERPC_AUTH_LEVEL_INTEGRITY: 432 354 /* Data is signed. */ 433 return auth_ntlmssp_check_packet(auth_state, 434 data->data, 435 data->length, 436 full_pkt->data, 437 full_pkt->length, 438 auth_token); 439 440 default: 441 return NT_STATUS_INVALID_PARAMETER; 442 } 443 } 444 445 /******************************************************************* 446 Create and add the schannel sign/seal auth data. 447 ********************************************************************/ 448 449 static NTSTATUS add_schannel_auth_footer(struct schannel_state *sas, 450 enum dcerpc_AuthLevel auth_level, 451 DATA_BLOB *rpc_out) 452 { 453 uint8_t *data_p = rpc_out->data + DCERPC_RESPONSE_LENGTH; 454 size_t data_and_pad_len = rpc_out->length 455 - DCERPC_RESPONSE_LENGTH 456 - DCERPC_AUTH_TRAILER_LENGTH; 457 DATA_BLOB auth_blob; 458 NTSTATUS status; 459 460 if (!sas) { 461 return NT_STATUS_INVALID_PARAMETER; 462 } 463 464 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n", 465 sas->seq_num)); 466 467 switch (auth_level) { 468 case DCERPC_AUTH_LEVEL_PRIVACY: 469 status = netsec_outgoing_packet(sas, 470 rpc_out->data, 471 true, 472 data_p, 473 data_and_pad_len, 474 &auth_blob); 475 break; 476 case DCERPC_AUTH_LEVEL_INTEGRITY: 477 status = netsec_outgoing_packet(sas, 478 rpc_out->data, 479 false, 480 data_p, 481 data_and_pad_len, 482 &auth_blob); 483 break; 484 default: 485 status = NT_STATUS_INTERNAL_ERROR; 486 break; 487 } 488 489 if (!NT_STATUS_IS_OK(status)) { 490 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n", 491 nt_errstr(status))); 492 return status; 493 } 494 495 if (DEBUGLEVEL >= 10) { 496 dump_NL_AUTH_SIGNATURE(talloc_tos(), &auth_blob); 497 } 498 499 /* Finally attach the blob. */ 500 if (!data_blob_append(NULL, rpc_out, 501 auth_blob.data, auth_blob.length)) { 502 return NT_STATUS_NO_MEMORY; 503 } 504 data_blob_free(&auth_blob); 505 506 return NT_STATUS_OK; 507 } 508 509 /******************************************************************* 510 Check/unseal the Schannel auth data. (Unseal in place). 511 ********************************************************************/ 512 513 static NTSTATUS get_schannel_auth_footer(TALLOC_CTX *mem_ctx, 514 struct schannel_state *auth_state, 515 enum dcerpc_AuthLevel auth_level, 516 DATA_BLOB *data, DATA_BLOB *full_pkt, 517 DATA_BLOB *auth_token) 518 { 519 switch (auth_level) { 520 case DCERPC_AUTH_LEVEL_PRIVACY: 521 /* Data portion is encrypted. */ 522 return netsec_incoming_packet(auth_state, 523 mem_ctx, true, 524 data->data, 525 data->length, 526 auth_token); 527 528 case DCERPC_AUTH_LEVEL_INTEGRITY: 529 /* Data is signed. */ 530 return netsec_incoming_packet(auth_state, 531 mem_ctx, false, 532 data->data, 533 data->length, 534 auth_token); 535 536 default: 537 return NT_STATUS_INVALID_PARAMETER; 538 } 539 } 540 541 /******************************************************************* 542 Create and add the gssapi sign/seal auth data. 543 ********************************************************************/ 544 545 static NTSTATUS add_gssapi_auth_footer(struct gse_context *gse_ctx, 546 enum dcerpc_AuthLevel auth_level, 547 DATA_BLOB *rpc_out) 548 { 549 DATA_BLOB data; 550 DATA_BLOB auth_blob; 551 NTSTATUS status; 552 553 if (!gse_ctx) { 554 return NT_STATUS_INVALID_PARAMETER; 555 } 556 557 data.data = rpc_out->data + DCERPC_RESPONSE_LENGTH; 558 data.length = rpc_out->length - DCERPC_RESPONSE_LENGTH 559 - DCERPC_AUTH_TRAILER_LENGTH; 560 561 switch (auth_level) { 562 case DCERPC_AUTH_LEVEL_PRIVACY: 563 status = gse_seal(talloc_tos(), gse_ctx, &data, &auth_blob); 564 break; 565 case DCERPC_AUTH_LEVEL_INTEGRITY: 566 status = gse_sign(talloc_tos(), gse_ctx, &data, &auth_blob); 567 break; 568 default: 569 status = NT_STATUS_INTERNAL_ERROR; 570 break; 571 } 572 573 if (!NT_STATUS_IS_OK(status)) { 574 DEBUG(1, ("Failed to process packet: %s\n", 575 nt_errstr(status))); 576 return status; 577 } 578 579 /* Finally attach the blob. */ 580 if (!data_blob_append(NULL, rpc_out, 581 auth_blob.data, auth_blob.length)) { 582 return NT_STATUS_NO_MEMORY; 583 } 584 585 data_blob_free(&auth_blob); 586 587 return NT_STATUS_OK; 588 } 589 590 /******************************************************************* 591 Check/unseal the gssapi auth data. (Unseal in place). 592 ********************************************************************/ 593 594 static NTSTATUS get_gssapi_auth_footer(TALLOC_CTX *mem_ctx, 595 struct gse_context *gse_ctx, 596 enum dcerpc_AuthLevel auth_level, 597 DATA_BLOB *data, DATA_BLOB *full_pkt, 598 DATA_BLOB *auth_token) 599 { 600 /* TODO: pass in full_pkt when 601 * DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN is set */ 602 switch (auth_level) { 603 case DCERPC_AUTH_LEVEL_PRIVACY: 604 /* Data portion is encrypted. */ 605 return gse_unseal(mem_ctx, gse_ctx, 606 data, auth_token); 607 608 case DCERPC_AUTH_LEVEL_INTEGRITY: 609 /* Data is signed. */ 610 return gse_sigcheck(mem_ctx, gse_ctx, 611 data, auth_token); 612 default: 613 return NT_STATUS_INVALID_PARAMETER; 614 } 615 } 616 617 /******************************************************************* 618 Create and add the spnego-negotiated sign/seal auth data. 619 ********************************************************************/ 620 621 static NTSTATUS add_spnego_auth_footer(struct spnego_context *spnego_ctx, 622 enum dcerpc_AuthLevel auth_level, 623 DATA_BLOB *rpc_out) 624 { 625 DATA_BLOB auth_blob; 626 DATA_BLOB rpc_data; 627 NTSTATUS status; 628 629 if (!spnego_ctx) { 630 return NT_STATUS_INVALID_PARAMETER; 631 } 632 633 rpc_data = data_blob_const(rpc_out->data 634 + DCERPC_RESPONSE_LENGTH, 635 rpc_out->length 636 - DCERPC_RESPONSE_LENGTH 637 - DCERPC_AUTH_TRAILER_LENGTH); 638 639 switch (auth_level) { 640 case DCERPC_AUTH_LEVEL_PRIVACY: 641 /* Data portion is encrypted. */ 642 status = spnego_seal(rpc_out->data, spnego_ctx, 643 &rpc_data, rpc_out, &auth_blob); 644 break; 645 646 if (!NT_STATUS_IS_OK(status)) { 647 return status; 648 } 649 break; 650 651 case DCERPC_AUTH_LEVEL_INTEGRITY: 652 /* Data is signed. */ 653 status = spnego_sign(rpc_out->data, spnego_ctx, 654 &rpc_data, rpc_out, &auth_blob); 655 break; 656 657 if (!NT_STATUS_IS_OK(status)) { 658 return status; 659 } 660 break; 661 662 default: 663 /* Can't happen. */ 664 smb_panic("bad auth level"); 665 /* Notreached. */ 666 return NT_STATUS_INVALID_PARAMETER; 667 } 668 669 /* Finally attach the blob. */ 670 if (!data_blob_append(NULL, rpc_out, 671 auth_blob.data, auth_blob.length)) { 672 DEBUG(0, ("Failed to add %u bytes auth blob.\n", 673 (unsigned int)auth_blob.length)); 674 return NT_STATUS_NO_MEMORY; 675 } 676 data_blob_free(&auth_blob); 677 678 return NT_STATUS_OK; 679 } 680 681 static NTSTATUS get_spnego_auth_footer(TALLOC_CTX *mem_ctx, 682 struct spnego_context *sp_ctx, 683 enum dcerpc_AuthLevel auth_level, 684 DATA_BLOB *data, DATA_BLOB *full_pkt, 685 DATA_BLOB *auth_token) 686 { 687 switch (auth_level) { 688 case DCERPC_AUTH_LEVEL_PRIVACY: 689 /* Data portion is encrypted. */ 690 return spnego_unseal(mem_ctx, sp_ctx, 691 data, full_pkt, auth_token); 692 693 case DCERPC_AUTH_LEVEL_INTEGRITY: 694 /* Data is signed. */ 695 return spnego_sigcheck(mem_ctx, sp_ctx, 696 data, full_pkt, auth_token); 355 return gensec_check_packet(gensec_security, 356 data->data, 357 data->length, 358 full_pkt->data, 359 full_pkt->length, 360 auth_token); 697 361 698 362 default: … … 713 377 size_t pad_len, DATA_BLOB *rpc_out) 714 378 { 715 struct schannel_state *schannel_auth; 716 struct auth_ntlmssp_state *ntlmssp_ctx; 717 struct spnego_context *spnego_ctx; 718 struct gse_context *gse_ctx; 719 char pad[CLIENT_NDR_PADDING_SIZE] = { 0, }; 379 struct gensec_security *gensec_security; 380 const char pad[DCERPC_AUTH_PAD_ALIGNMENT] = { 0, }; 720 381 DATA_BLOB auth_info; 721 382 DATA_BLOB auth_blob; 722 383 NTSTATUS status; 723 384 724 if (auth->auth_type == DCERPC_AUTH_TYPE_NONE || 725 auth->auth_type == DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM) { 385 if (auth->auth_type == DCERPC_AUTH_TYPE_NONE) { 726 386 return NT_STATUS_OK; 727 387 } 728 388 729 389 if (pad_len) { 390 SMB_ASSERT(pad_len <= ARRAY_SIZE(pad)); 391 730 392 /* Copy the sign/seal padding data. */ 731 393 if (!data_blob_append(NULL, rpc_out, pad, pad_len)) { … … 761 423 switch (auth->auth_type) { 762 424 case DCERPC_AUTH_TYPE_NONE: 763 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:764 425 status = NT_STATUS_OK; 765 426 break; 766 case DCERPC_AUTH_TYPE_SPNEGO: 767 spnego_ctx = talloc_get_type_abort(auth->auth_ctx, 768 struct spnego_context); 769 status = add_spnego_auth_footer(spnego_ctx, 770 auth->auth_level, rpc_out); 771 break; 772 case DCERPC_AUTH_TYPE_NTLMSSP: 773 ntlmssp_ctx = talloc_get_type_abort(auth->auth_ctx, 774 struct auth_ntlmssp_state); 775 status = add_ntlmssp_auth_footer(ntlmssp_ctx, 427 default: 428 gensec_security = auth->auth_ctx; 429 status = add_generic_auth_footer(gensec_security, 776 430 auth->auth_level, 777 431 rpc_out); 778 break;779 case DCERPC_AUTH_TYPE_SCHANNEL:780 schannel_auth = talloc_get_type_abort(auth->auth_ctx,781 struct schannel_state);782 status = add_schannel_auth_footer(schannel_auth,783 auth->auth_level,784 rpc_out);785 break;786 case DCERPC_AUTH_TYPE_KRB5:787 gse_ctx = talloc_get_type_abort(auth->auth_ctx,788 struct gse_context);789 status = add_gssapi_auth_footer(gse_ctx,790 auth->auth_level,791 rpc_out);792 break;793 default:794 status = NT_STATUS_INVALID_PARAMETER;795 432 break; 796 433 } … … 817 454 DATA_BLOB *raw_pkt) 818 455 { 819 struct schannel_state *schannel_auth; 820 struct auth_ntlmssp_state *ntlmssp_ctx; 821 struct spnego_context *spnego_ctx; 822 struct gse_context *gse_ctx; 456 struct gensec_security *gensec_security; 823 457 NTSTATUS status; 824 458 struct dcerpc_auth auth_info; … … 894 528 switch (auth->auth_type) { 895 529 case DCERPC_AUTH_TYPE_NONE: 896 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:897 530 return NT_STATUS_OK; 898 531 899 case DCERPC_AUTH_TYPE_SPNEGO: 900 spnego_ctx = talloc_get_type_abort(auth->auth_ctx, 901 struct spnego_context); 902 status = get_spnego_auth_footer(pkt, spnego_ctx, 903 auth->auth_level, 904 &data, &full_pkt, 905 &auth_info.credentials); 906 if (!NT_STATUS_IS_OK(status)) { 907 return status; 908 } 909 break; 910 911 case DCERPC_AUTH_TYPE_NTLMSSP: 912 913 DEBUG(10, ("NTLMSSP auth\n")); 914 915 ntlmssp_ctx = talloc_get_type_abort(auth->auth_ctx, 916 struct auth_ntlmssp_state); 917 status = get_ntlmssp_auth_footer(ntlmssp_ctx, 532 default: 533 DEBUG(10, ("GENSEC auth\n")); 534 535 gensec_security = auth->auth_ctx; 536 status = get_generic_auth_footer(gensec_security, 918 537 auth->auth_level, 919 538 &data, &full_pkt, … … 923 542 } 924 543 break; 925 926 case DCERPC_AUTH_TYPE_SCHANNEL:927 928 DEBUG(10, ("SCHANNEL auth\n"));929 930 schannel_auth = talloc_get_type_abort(auth->auth_ctx,931 struct schannel_state);932 status = get_schannel_auth_footer(pkt, schannel_auth,933 auth->auth_level,934 &data, &full_pkt,935 &auth_info.credentials);936 if (!NT_STATUS_IS_OK(status)) {937 return status;938 }939 break;940 941 case DCERPC_AUTH_TYPE_KRB5:942 943 DEBUG(10, ("KRB5 auth\n"));944 945 gse_ctx = talloc_get_type_abort(auth->auth_ctx,946 struct gse_context);947 status = get_gssapi_auth_footer(pkt, gse_ctx,948 auth->auth_level,949 &data, &full_pkt,950 &auth_info.credentials);951 if (!NT_STATUS_IS_OK(status)) {952 return status;953 }954 break;955 956 default:957 DEBUG(0, ("process_request_pdu: "958 "unknown auth type %u set.\n",959 (unsigned int)auth->auth_type));960 return NT_STATUS_INVALID_PARAMETER;961 544 } 962 545 -
vendor/current/source3/librpc/wscript_build
r740 r988 8 8 bld.SAMBA3_SUBSYSTEM('NDR_LIBNET_JOIN', 9 9 source='gen_ndr/ndr_libnet_join.c', 10 public_deps='ndr '10 public_deps='ndr krb5samba' 11 11 ) 12 12 13 bld.SAMBA3_SUBSYSTEM('NDR_ SERVER_ID',14 source='gen_ndr/ndr_ server_id.c',15 public_deps='ndr '13 bld.SAMBA3_SUBSYSTEM('NDR_OPEN_FILES', 14 source='gen_ndr/ndr_open_files.c', 15 public_deps='ndr NDR_SERVER_ID NDR_FILE_ID NDR_SECURITY NDR_SMB2_LEASE_STRUCT' 16 16 ) 17 17 18 bld.SAMBA3_SUBSYSTEM('NDR_ MESSAGING',19 source='gen_ndr/ndr_ messaging.c',20 public_deps='ndr NDR_SERVER_ID '18 bld.SAMBA3_SUBSYSTEM('NDR_SMBXSRV', 19 source='gen_ndr/ndr_smbXsrv.c', 20 public_deps='ndr NDR_SERVER_ID NDR_SECURITY NDR_AUTH' 21 21 ) 22 22 23 bld.SAMBA3_SUBSYSTEM('NDR_ NOTIFY3',24 source='gen_ndr/ndr_ notify.c',25 public_deps='ndr NDR_FILE_ID NDR_SERVER_ID'23 bld.SAMBA3_SUBSYSTEM('NDR_LEASES_DB', 24 source='gen_ndr/ndr_leases_db.c', 25 public_deps='ndr' 26 26 ) 27 27 … … 36 36 ) 37 37 38 bld.SAMBA3_SUBSYSTEM('NDR_WBINT',39 source='gen_ndr/ndr_wbint.c',40 public_deps='ndr'41 )42 43 bld.SAMBA3_SUBSYSTEM('RPC_NDR_WBINT',44 source='../librpc/gen_ndr/ndr_wbint_c.c',45 public_deps='dcerpc NDR_WBINT'46 )47 48 bld.SAMBA3_SUBSYSTEM('SRV_NDR_WBINT',49 source='../librpc/gen_ndr/srv_wbint.c',50 public_deps='NDR_WBINT'51 )
Note:
See TracChangeset
for help on using the changeset viewer.