Changeset 740 for vendor/current/source4/rpc_server/dcesrv_auth.c
- Timestamp:
- Nov 14, 2012, 12:59:34 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified vendor/current/source4/rpc_server/dcesrv_auth.c ¶
r414 r740 24 24 #include "rpc_server/dcerpc_server.h" 25 25 #include "rpc_server/dcerpc_server_proto.h" 26 #include "rpc_server/common/proto.h" 26 27 #include "librpc/rpc/dcerpc_proto.h" 27 28 #include "librpc/gen_ndr/ndr_dcerpc.h" … … 30 31 #include "auth/auth.h" 31 32 #include "param/param.h" 33 #include "librpc/rpc/rpc_common.h" 32 34 33 35 /* … … 43 45 struct dcesrv_auth *auth = &dce_conn->auth_state; 44 46 NTSTATUS status; 45 enum ndr_err_code ndr_err;47 uint32_t auth_length; 46 48 47 49 if (pkt->u.bind.auth_info.length == 0) { … … 55 57 } 56 58 57 ndr_err = ndr_pull_struct_blob(&pkt->u.bind.auth_info, 58 call, NULL, 59 dce_conn->auth_state.auth_info, 60 (ndr_pull_flags_fn_t)ndr_pull_dcerpc_auth); 61 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 62 return false; 63 } 64 59 status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.bind.auth_info, 60 dce_conn->auth_state.auth_info, 61 &auth_length, false); 65 62 server_credentials 66 63 = cli_credentials_init(call); … … 80 77 status = samba_server_gensec_start(dce_conn, call->event_ctx, 81 78 call->msg_ctx, 82 call->conn->dce_ctx->lp_ctx, 79 call->conn->dce_ctx->lp_ctx, 83 80 server_credentials, 84 81 NULL, … … 89 86 90 87 if (!NT_STATUS_IS_OK(status)) { 91 DEBUG( 1, ("Failed to start GENSEC mechanism for DCERPC server: auth_type=%d, auth_level=%d: %s\n",88 DEBUG(3, ("Failed to start GENSEC mechanism for DCERPC server: auth_type=%d, auth_level=%d: %s\n", 92 89 (int)auth->auth_info->auth_type, 93 90 (int)auth->auth_info->auth_level, … … 142 139 return NT_STATUS_OK; 143 140 } else { 144 DEBUG(2, ("Failed to start dcesrv auth negotiate: %s\n", nt_errstr(status))); 141 DEBUG(4, ("GENSEC mech rejected the incoming authentication at bind_ack: %s\n", 142 nt_errstr(status))); 145 143 return status; 146 144 } … … 156 154 struct dcesrv_connection *dce_conn = call->conn; 157 155 NTSTATUS status; 158 enum ndr_err_code ndr_err;156 uint32_t auth_length; 159 157 160 158 /* We can't work without an existing gensec state, and an new blob to feed it */ … … 165 163 } 166 164 167 ndr_err = ndr_pull_struct_blob(&pkt->u.auth3.auth_info, 168 call, NULL, 169 dce_conn->auth_state.auth_info, 170 (ndr_pull_flags_fn_t)ndr_pull_dcerpc_auth); 171 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 165 status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.auth3.auth_info, 166 dce_conn->auth_state.auth_info, &auth_length, true); 167 if (!NT_STATUS_IS_OK(status)) { 172 168 return false; 173 169 } … … 189 185 return true; 190 186 } else { 191 DEBUG(4, (" dcesrv_auth_auth3: failed to authenticate: %s\n",187 DEBUG(4, ("GENSEC mech rejected the incoming authentication at bind_auth3: %s\n", 192 188 nt_errstr(status))); 193 189 return false; 194 190 } 195 196 return true;197 191 } 198 192 … … 206 200 struct ncacn_packet *pkt = &call->pkt; 207 201 struct dcesrv_connection *dce_conn = call->conn; 208 enum ndr_err_code ndr_err; 202 NTSTATUS status; 203 uint32_t auth_length; 209 204 210 205 /* on a pure interface change there is no auth blob */ … … 223 218 } 224 219 225 ndr_err = ndr_pull_struct_blob(&pkt->u.alter.auth_info, 226 call, NULL, 227 dce_conn->auth_state.auth_info, 228 (ndr_pull_flags_fn_t)ndr_pull_dcerpc_auth); 229 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 220 status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.alter.auth_info, 221 dce_conn->auth_state.auth_info, 222 &auth_length, true); 223 if (!NT_STATUS_IS_OK(status)) { 230 224 return false; 231 225 } … … 276 270 } 277 271 278 DEBUG(2, ("Failed to finish dcesrv auth alter_ack: %s\n", nt_errstr(status))); 272 DEBUG(4, ("GENSEC mech rejected the incoming authentication at auth alter_ack: %s\n", 273 nt_errstr(status))); 279 274 return status; 280 275 } … … 287 282 struct ncacn_packet *pkt = &call->pkt; 288 283 struct dcesrv_connection *dce_conn = call->conn; 289 DATA_BLOB auth_blob;290 284 struct dcerpc_auth auth; 291 struct ndr_pull *ndr; 292 NTSTATUS status; 293 enum ndr_err_code ndr_err; 285 NTSTATUS status; 286 uint32_t auth_length; 294 287 size_t hdr_size = DCERPC_REQUEST_LENGTH; 295 288 … … 297 290 !dce_conn->auth_state.gensec_security) { 298 291 return true; 292 } 293 294 if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) { 295 hdr_size += 16; 299 296 } 300 297 … … 319 316 } 320 317 321 auth_blob.length = 8 + pkt->auth_length; 322 323 /* check for a valid length */ 324 if (pkt->u.request.stub_and_verifier.length < auth_blob.length) { 325 return false; 326 } 327 328 auth_blob.data = 329 pkt->u.request.stub_and_verifier.data + 330 pkt->u.request.stub_and_verifier.length - auth_blob.length; 331 pkt->u.request.stub_and_verifier.length -= auth_blob.length; 332 333 /* pull the auth structure */ 334 ndr = ndr_pull_init_blob(&auth_blob, call, lp_iconv_convenience(call->conn->dce_ctx->lp_ctx)); 335 if (!ndr) { 336 return false; 337 } 338 339 if (!(pkt->drep[0] & DCERPC_DREP_LE)) { 340 ndr->flags |= LIBNDR_FLAG_BIGENDIAN; 341 } 342 343 if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) { 344 ndr->flags |= LIBNDR_FLAG_OBJECT_PRESENT; 345 hdr_size += 16; 346 } 347 348 ndr_err = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, &auth); 349 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 350 talloc_free(ndr); 351 return false; 352 } 318 status = dcerpc_pull_auth_trailer(pkt, call, 319 &pkt->u.request.stub_and_verifier, 320 &auth, &auth_length, false); 321 if (!NT_STATUS_IS_OK(status)) { 322 return false; 323 } 324 325 pkt->u.request.stub_and_verifier.length -= auth_length; 353 326 354 327 /* check signature or unseal the packet */ … … 389 362 /* remove the indicated amount of padding */ 390 363 if (pkt->u.request.stub_and_verifier.length < auth.auth_pad_length) { 391 talloc_free(ndr);392 364 return false; 393 365 } 394 366 pkt->u.request.stub_and_verifier.length -= auth.auth_pad_length; 395 talloc_free(ndr);396 367 397 368 return NT_STATUS_IS_OK(status); … … 415 386 /* non-signed packets are simple */ 416 387 if (sig_size == 0) { 417 status = ncacn_push_auth(blob, call, lp_iconv_convenience(dce_conn->dce_ctx->lp_ctx),pkt, NULL);388 status = ncacn_push_auth(blob, call, pkt, NULL); 418 389 return NT_STATUS_IS_OK(status); 419 390 } … … 426 397 case DCERPC_AUTH_LEVEL_CONNECT: 427 398 /* 428 * TODO: let the gensec mech decide if it wants to generate a signature429 * that might be needed for schannel...399 * TODO: let the gensec mech decide if it wants to generate a 400 * signature that might be needed for schannel... 430 401 */ 431 status = ncacn_push_auth(blob, call, lp_iconv_convenience(dce_conn->dce_ctx->lp_ctx),pkt, NULL);402 status = ncacn_push_auth(blob, call, pkt, NULL); 432 403 return NT_STATUS_IS_OK(status); 433 404 434 405 case DCERPC_AUTH_LEVEL_NONE: 435 status = ncacn_push_auth(blob, call, lp_iconv_convenience(dce_conn->dce_ctx->lp_ctx),pkt, NULL);406 status = ncacn_push_auth(blob, call, pkt, NULL); 436 407 return NT_STATUS_IS_OK(status); 437 408 … … 440 411 } 441 412 442 ndr = ndr_push_init_ctx(call , lp_iconv_convenience(dce_conn->dce_ctx->lp_ctx));413 ndr = ndr_push_init_ctx(call); 443 414 if (!ndr) { 444 415 return false; … … 454 425 } 455 426 456 /* pad to 16 byte multiple, match win2k3 */ 427 /* pad to 16 byte multiple in the payload portion of the 428 packet. This matches what w2k3 does. Note that we can't use 429 ndr_push_align() as that is relative to the start of the 430 whole packet, whereas w2k8 wants it relative to the start 431 of the stub */ 457 432 dce_conn->auth_state.auth_info->auth_pad_length = 458 433 (16 - (pkt->u.response.stub_and_verifier.length & 15)) & 15; 459 ndr_err = ndr_push_zero(ndr, dce_conn->auth_state.auth_info->auth_pad_length); 434 ndr_err = ndr_push_zero(ndr, 435 dce_conn->auth_state.auth_info->auth_pad_length); 460 436 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 461 437 return false; … … 470 446 /* add the auth verifier */ 471 447 ndr_err = ndr_push_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, 472 dce_conn->auth_state.auth_info);448 dce_conn->auth_state.auth_info); 473 449 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 474 450 return false; … … 514 490 } 515 491 516 if (NT_STATUS_IS_OK(status)) {517 if (creds2.length != sig_size) {518 DEBUG(0,("dcesrv_auth_response: creds2.length[%u] != sig_size[%u] pad[%u] stub[%u]\n",519 (unsigned)creds2.length, (uint32_t)sig_size,520 (unsigned)dce_conn->auth_state.auth_info->auth_pad_length,521 (unsigned)pkt->u.response.stub_and_verifier.length));522 data_blob_free(&creds2);523 status = NT_STATUS_INTERNAL_ERROR;524 }525 }526 527 if (NT_STATUS_IS_OK(status)) {528 if (!data_blob_append(call, blob, creds2.data, creds2.length)) {529 status = NT_STATUS_NO_MEMORY;530 }531 data_blob_free(&creds2);532 }533 534 492 if (!NT_STATUS_IS_OK(status)) { 535 493 return false; 536 494 } 537 495 496 if (creds2.length != sig_size) { 497 DEBUG(3,("dcesrv_auth_response: creds2.length[%u] != sig_size[%u] pad[%u] stub[%u]\n", 498 (unsigned)creds2.length, (uint32_t)sig_size, 499 (unsigned)dce_conn->auth_state.auth_info->auth_pad_length, 500 (unsigned)pkt->u.response.stub_and_verifier.length)); 501 dcerpc_set_frag_length(blob, blob->length + creds2.length); 502 dcerpc_set_auth_length(blob, creds2.length); 503 } 504 505 if (!data_blob_append(call, blob, creds2.data, creds2.length)) { 506 status = NT_STATUS_NO_MEMORY; 507 return false; 508 } 509 data_blob_free(&creds2); 510 538 511 return true; 539 512 }
Note:
See TracChangeset
for help on using the changeset viewer.