00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "includes.h"
00022
00023 #undef DBGC_CLASS
00024 #define DBGC_CLASS DBGC_RPC_CLI
00025
00026 extern struct pipe_id_info pipe_names[];
00027
00028
00029
00030
00031
00032 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
00033 {
00034 switch (auth_type) {
00035
00036 case PIPE_AUTH_TYPE_NONE:
00037 return RPC_ANONYMOUS_AUTH_TYPE;
00038
00039 case PIPE_AUTH_TYPE_NTLMSSP:
00040 return RPC_NTLMSSP_AUTH_TYPE;
00041
00042 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
00043 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
00044 return RPC_SPNEGO_AUTH_TYPE;
00045
00046 case PIPE_AUTH_TYPE_SCHANNEL:
00047 return RPC_SCHANNEL_AUTH_TYPE;
00048
00049 case PIPE_AUTH_TYPE_KRB5:
00050 return RPC_KRB5_AUTH_TYPE;
00051
00052 default:
00053 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
00054 "auth type %u\n",
00055 (unsigned int)auth_type ));
00056 break;
00057 }
00058 return -1;
00059 }
00060
00061
00062
00063
00064
00065 static uint32 get_rpc_call_id(void)
00066 {
00067 static uint32 call_id = 0;
00068 return ++call_id;
00069 }
00070
00071
00072
00073
00074
00075
00076 static NTSTATUS rpc_read(struct rpc_pipe_client *cli,
00077 prs_struct *current_pdu,
00078 uint32 data_to_read,
00079 uint32 *current_pdu_offset)
00080 {
00081 size_t size = (size_t)cli->max_recv_frag;
00082 uint32 stream_offset = 0;
00083 ssize_t num_read;
00084 char *pdata;
00085 ssize_t extra_data_size = ((ssize_t)*current_pdu_offset) + ((ssize_t)data_to_read) - (ssize_t)prs_data_size(current_pdu);
00086
00087 DEBUG(5,("rpc_read: data_to_read: %u current_pdu offset: %u extra_data_size: %d\n",
00088 (unsigned int)data_to_read, (unsigned int)*current_pdu_offset, (int)extra_data_size ));
00089
00090
00091
00092
00093
00094 if (extra_data_size > 0) {
00095 if(!prs_force_grow(current_pdu, (uint32)extra_data_size)) {
00096 DEBUG(0,("rpc_read: Failed to grow parse struct by %d bytes.\n", (int)extra_data_size ));
00097 return NT_STATUS_NO_MEMORY;
00098 }
00099 DEBUG(5,("rpc_read: grew buffer by %d bytes to %u\n", (int)extra_data_size, prs_data_size(current_pdu) ));
00100 }
00101
00102 pdata = prs_data_p(current_pdu) + *current_pdu_offset;
00103
00104 do {
00105
00106 if (size > (size_t)data_to_read) {
00107 size = (size_t)data_to_read;
00108 }
00109
00110 num_read = cli_read(cli->cli, cli->fnum, pdata,
00111 (off_t)stream_offset, size);
00112
00113 DEBUG(5,("rpc_read: num_read = %d, read offset: %u, to read: %u\n",
00114 (int)num_read, (unsigned int)stream_offset, (unsigned int)data_to_read));
00115
00116
00117
00118
00119 if (cli_is_dos_error(cli->cli)) {
00120 uint32 ecode;
00121 uint8 eclass;
00122 cli_dos_error(cli->cli, &eclass, &ecode);
00123 if (eclass != ERRDOS && ecode != ERRmoredata) {
00124 DEBUG(0,("rpc_read: DOS Error %d/%u (%s) in cli_read on pipe %s\n",
00125 eclass, (unsigned int)ecode,
00126 cli_errstr(cli->cli),
00127 cli->pipe_name ));
00128 return dos_to_ntstatus(eclass, ecode);
00129 }
00130 }
00131
00132
00133
00134
00135 if (cli_is_nt_error(cli->cli)) {
00136 if (!NT_STATUS_EQUAL(cli_nt_error(cli->cli), NT_STATUS_BUFFER_TOO_SMALL)) {
00137 DEBUG(0,("rpc_read: Error (%s) in cli_read on pipe %s\n",
00138 nt_errstr(cli_nt_error(cli->cli)),
00139 cli->pipe_name ));
00140 return cli_nt_error(cli->cli);
00141 }
00142 }
00143
00144 if (num_read == -1) {
00145 DEBUG(0,("rpc_read: Error - cli_read on pipe %s returned -1\n",
00146 cli->pipe_name ));
00147 return cli_get_nt_error(cli->cli);
00148 }
00149
00150 data_to_read -= num_read;
00151 stream_offset += num_read;
00152 pdata += num_read;
00153
00154 } while (num_read > 0 && data_to_read > 0);
00155
00156
00157
00158
00159
00160 *current_pdu_offset += stream_offset;
00161 return NT_STATUS_OK;
00162 }
00163
00164
00165
00166
00167
00168
00169 static NTSTATUS cli_pipe_get_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
00170 {
00171 NTSTATUS ret = NT_STATUS_OK;
00172 uint32 current_pdu_len = prs_data_size(current_pdu);
00173
00174
00175 if (current_pdu_len < RPC_HEADER_LEN) {
00176
00177 ret = rpc_read(cli, current_pdu, RPC_HEADER_LEN - current_pdu_len, ¤t_pdu_len);
00178 if (!NT_STATUS_IS_OK(ret)) {
00179 return ret;
00180 }
00181 }
00182
00183
00184
00185 if(!smb_io_rpc_hdr("rpc_hdr ", prhdr, current_pdu, 0)) {
00186 DEBUG(0,("cli_pipe_get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
00187 return NT_STATUS_BUFFER_TOO_SMALL;
00188 }
00189
00190
00191 if (current_pdu_len < prhdr->frag_len) {
00192
00193 ret = rpc_read(cli, current_pdu, (uint32)prhdr->frag_len - current_pdu_len, ¤t_pdu_len);
00194 if (!NT_STATUS_IS_OK(ret)) {
00195 return ret;
00196 }
00197 }
00198
00199 if (current_pdu_len < prhdr->frag_len) {
00200 return NT_STATUS_BUFFER_TOO_SMALL;
00201 }
00202
00203 return NT_STATUS_OK;
00204 }
00205
00206
00207
00208
00209
00210
00211
00212 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
00213 prs_struct *current_pdu,
00214 uint8 *p_ss_padding_len)
00215 {
00216 RPC_HDR_AUTH auth_info;
00217 uint32 save_offset = prs_offset(current_pdu);
00218 uint32 auth_len = prhdr->auth_len;
00219 NTLMSSP_STATE *ntlmssp_state = cli->auth.a_u.ntlmssp_state;
00220 unsigned char *data = NULL;
00221 size_t data_len;
00222 unsigned char *full_packet_data = NULL;
00223 size_t full_packet_data_len;
00224 DATA_BLOB auth_blob;
00225 NTSTATUS status;
00226
00227 if (cli->auth.auth_level == PIPE_AUTH_LEVEL_NONE || cli->auth.auth_level == PIPE_AUTH_LEVEL_CONNECT) {
00228 return NT_STATUS_OK;
00229 }
00230
00231 if (!ntlmssp_state) {
00232 return NT_STATUS_INVALID_PARAMETER;
00233 }
00234
00235
00236 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
00237 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
00238 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
00239 (unsigned int)auth_len ));
00240 return NT_STATUS_BUFFER_TOO_SMALL;
00241 }
00242
00243
00244
00245
00246
00247
00248
00249
00250 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
00251 data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
00252
00253 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
00254 full_packet_data_len = prhdr->frag_len - auth_len;
00255
00256
00257 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
00258 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
00259 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
00260 return NT_STATUS_BUFFER_TOO_SMALL;
00261 }
00262
00263 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
00264 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
00265 return NT_STATUS_BUFFER_TOO_SMALL;
00266 }
00267
00268 auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
00269 auth_blob.length = auth_len;
00270
00271 switch (cli->auth.auth_level) {
00272 case PIPE_AUTH_LEVEL_PRIVACY:
00273
00274 status = ntlmssp_unseal_packet(ntlmssp_state,
00275 data, data_len,
00276 full_packet_data,
00277 full_packet_data_len,
00278 &auth_blob);
00279 if (!NT_STATUS_IS_OK(status)) {
00280 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
00281 "packet from remote machine %s on pipe %s "
00282 "fnum 0x%x. Error was %s.\n",
00283 cli->cli->desthost,
00284 cli->pipe_name,
00285 (unsigned int)cli->fnum,
00286 nt_errstr(status) ));
00287 return status;
00288 }
00289 break;
00290 case PIPE_AUTH_LEVEL_INTEGRITY:
00291
00292 status = ntlmssp_check_packet(ntlmssp_state,
00293 data, data_len,
00294 full_packet_data,
00295 full_packet_data_len,
00296 &auth_blob);
00297 if (!NT_STATUS_IS_OK(status)) {
00298 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
00299 "packet from remote machine %s on pipe %s "
00300 "fnum 0x%x. Error was %s.\n",
00301 cli->cli->desthost,
00302 cli->pipe_name,
00303 (unsigned int)cli->fnum,
00304 nt_errstr(status) ));
00305 return status;
00306 }
00307 break;
00308 default:
00309 DEBUG(0,("cli_pipe_verify_ntlmssp: unknown internal auth level %d\n",
00310 cli->auth.auth_level ));
00311 return NT_STATUS_INVALID_INFO_CLASS;
00312 }
00313
00314
00315
00316
00317
00318 if(!prs_set_offset(current_pdu, save_offset)) {
00319 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
00320 (unsigned int)save_offset ));
00321 return NT_STATUS_BUFFER_TOO_SMALL;
00322 }
00323
00324
00325
00326
00327
00328
00329 *p_ss_padding_len = auth_info.auth_pad_len;
00330
00331 return NT_STATUS_OK;
00332 }
00333
00334
00335
00336
00337
00338 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
00339 prs_struct *current_pdu,
00340 uint8 *p_ss_padding_len)
00341 {
00342 RPC_HDR_AUTH auth_info;
00343 RPC_AUTH_SCHANNEL_CHK schannel_chk;
00344 uint32 auth_len = prhdr->auth_len;
00345 uint32 save_offset = prs_offset(current_pdu);
00346 struct schannel_auth_struct *schannel_auth = cli->auth.a_u.schannel_auth;
00347 uint32 data_len;
00348
00349 if (cli->auth.auth_level == PIPE_AUTH_LEVEL_NONE || cli->auth.auth_level == PIPE_AUTH_LEVEL_CONNECT) {
00350 return NT_STATUS_OK;
00351 }
00352
00353 if (auth_len != RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
00354 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
00355 return NT_STATUS_INVALID_PARAMETER;
00356 }
00357
00358 if (!schannel_auth) {
00359 return NT_STATUS_INVALID_PARAMETER;
00360 }
00361
00362
00363 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
00364 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
00365 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
00366 (unsigned int)auth_len ));
00367 return NT_STATUS_INVALID_PARAMETER;
00368 }
00369
00370 data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
00371
00372 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
00373 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
00374 (unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));
00375 return NT_STATUS_BUFFER_TOO_SMALL;
00376 }
00377
00378 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
00379 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
00380 return NT_STATUS_BUFFER_TOO_SMALL;
00381 }
00382
00383 if (auth_info.auth_type != RPC_SCHANNEL_AUTH_TYPE) {
00384 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
00385 auth_info.auth_type));
00386 return NT_STATUS_BUFFER_TOO_SMALL;
00387 }
00388
00389 if(!smb_io_rpc_auth_schannel_chk("", RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
00390 &schannel_chk, current_pdu, 0)) {
00391 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshal RPC_AUTH_SCHANNEL_CHK.\n"));
00392 return NT_STATUS_BUFFER_TOO_SMALL;
00393 }
00394
00395 if (!schannel_decode(schannel_auth,
00396 cli->auth.auth_level,
00397 SENDER_IS_ACCEPTOR,
00398 &schannel_chk,
00399 prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN,
00400 data_len)) {
00401 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
00402 "Connection to remote machine %s "
00403 "pipe %s fnum 0x%x.\n",
00404 cli->cli->desthost,
00405 cli->pipe_name,
00406 (unsigned int)cli->fnum ));
00407 return NT_STATUS_INVALID_PARAMETER;
00408 }
00409
00410
00411 schannel_auth->seq_num++;
00412
00413
00414
00415
00416
00417 if(!prs_set_offset(current_pdu, save_offset)) {
00418 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
00419 (unsigned int)save_offset ));
00420 return NT_STATUS_BUFFER_TOO_SMALL;
00421 }
00422
00423
00424
00425
00426
00427
00428 *p_ss_padding_len = auth_info.auth_pad_len;
00429
00430 return NT_STATUS_OK;
00431 }
00432
00433
00434
00435
00436
00437 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
00438 prs_struct *current_pdu,
00439 uint8 *p_ss_padding_len)
00440 {
00441 NTSTATUS ret = NT_STATUS_OK;
00442
00443
00444 if (prhdr->auth_len) {
00445 if (prhdr->auth_len > prhdr->frag_len) {
00446 return NT_STATUS_INVALID_PARAMETER;
00447 }
00448
00449 if (prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_len ||
00450 prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
00451
00452 return NT_STATUS_INVALID_PARAMETER;
00453 }
00454 }
00455
00456
00457
00458
00459
00460 switch(cli->auth.auth_type) {
00461 case PIPE_AUTH_TYPE_NONE:
00462 if (prhdr->auth_len) {
00463 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection to remote machine %s "
00464 "pipe %s fnum 0x%x - got non-zero auth len %u.\n",
00465 cli->cli->desthost,
00466 cli->pipe_name,
00467 (unsigned int)cli->fnum,
00468 (unsigned int)prhdr->auth_len ));
00469 return NT_STATUS_INVALID_PARAMETER;
00470 }
00471 break;
00472
00473 case PIPE_AUTH_TYPE_NTLMSSP:
00474 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
00475 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
00476 if (!NT_STATUS_IS_OK(ret)) {
00477 return ret;
00478 }
00479 break;
00480
00481 case PIPE_AUTH_TYPE_SCHANNEL:
00482 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
00483 if (!NT_STATUS_IS_OK(ret)) {
00484 return ret;
00485 }
00486 break;
00487
00488 case PIPE_AUTH_TYPE_KRB5:
00489 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
00490 default:
00491 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection to remote machine %s "
00492 "pipe %s fnum %x - unknown internal auth type %u.\n",
00493 cli->cli->desthost,
00494 cli->pipe_name,
00495 (unsigned int)cli->fnum,
00496 cli->auth.auth_type ));
00497 return NT_STATUS_INVALID_INFO_CLASS;
00498 }
00499
00500 return NT_STATUS_OK;
00501 }
00502
00503
00504
00505
00506
00507 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
00508 prs_struct *current_pdu,
00509 uint8 expected_pkt_type,
00510 char **ppdata,
00511 uint32 *pdata_len,
00512 prs_struct *return_data)
00513 {
00514
00515 NTSTATUS ret = NT_STATUS_OK;
00516 uint32 current_pdu_len = prs_data_size(current_pdu);
00517
00518 if (current_pdu_len != prhdr->frag_len) {
00519 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
00520 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
00521 return NT_STATUS_INVALID_PARAMETER;
00522 }
00523
00524
00525
00526
00527
00528 *ppdata = prs_data_p(current_pdu);
00529 *pdata_len = current_pdu_len;
00530
00531
00532 switch (prhdr->pkt_type) {
00533 case RPC_ALTCONTRESP:
00534 case RPC_BINDACK:
00535
00536
00537 break;
00538
00539
00540 case RPC_RESPONSE:
00541 {
00542 RPC_HDR_RESP rhdr_resp;
00543 uint8 ss_padding_len = 0;
00544
00545 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
00546 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
00547 return NT_STATUS_BUFFER_TOO_SMALL;
00548 }
00549
00550
00551 ret = cli_pipe_validate_rpc_response(cli, prhdr,
00552 current_pdu, &ss_padding_len);
00553 if (!NT_STATUS_IS_OK(ret)) {
00554 return ret;
00555 }
00556
00557
00558 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
00559
00560 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
00561 return NT_STATUS_BUFFER_TOO_SMALL;
00562 }
00563
00564 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
00565
00566
00567 if (prhdr->auth_len) {
00568
00569
00570 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
00571 return NT_STATUS_BUFFER_TOO_SMALL;
00572 }
00573 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
00574 }
00575
00576 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
00577 current_pdu_len, *pdata_len, ss_padding_len ));
00578
00579
00580
00581
00582
00583
00584 if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
00585 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
00586 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
00587 "too large to allocate\n",
00588 (unsigned int)rhdr_resp.alloc_hint ));
00589 return NT_STATUS_NO_MEMORY;
00590 }
00591 }
00592
00593 break;
00594 }
00595
00596 case RPC_BINDNACK:
00597 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK received from remote machine %s "
00598 "pipe %s fnum 0x%x!\n",
00599 cli->cli->desthost,
00600 cli->pipe_name,
00601 (unsigned int)cli->fnum));
00602
00603 return NT_STATUS_NETWORK_ACCESS_DENIED;
00604
00605 case RPC_FAULT:
00606 {
00607 RPC_HDR_RESP rhdr_resp;
00608 RPC_HDR_FAULT fault_resp;
00609
00610 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
00611 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
00612 return NT_STATUS_BUFFER_TOO_SMALL;
00613 }
00614
00615 if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
00616 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
00617 return NT_STATUS_BUFFER_TOO_SMALL;
00618 }
00619
00620 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault code %s received from remote machine %s "
00621 "pipe %s fnum 0x%x!\n",
00622 dcerpc_errstr(NT_STATUS_V(fault_resp.status)),
00623 cli->cli->desthost,
00624 cli->pipe_name,
00625 (unsigned int)cli->fnum));
00626 if (NT_STATUS_IS_OK(fault_resp.status)) {
00627 return NT_STATUS_UNSUCCESSFUL;
00628 } else {
00629 return fault_resp.status;
00630 }
00631
00632 }
00633
00634 default:
00635 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
00636 "from remote machine %s pipe %s fnum 0x%x!\n",
00637 (unsigned int)prhdr->pkt_type,
00638 cli->cli->desthost,
00639 cli->pipe_name,
00640 (unsigned int)cli->fnum));
00641 return NT_STATUS_INVALID_INFO_CLASS;
00642 }
00643
00644 if (prhdr->pkt_type != expected_pkt_type) {
00645 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to remote machine %s "
00646 "pipe %s fnum %x got an unexpected RPC packet "
00647 "type - %u, not %u\n",
00648 cli->cli->desthost,
00649 cli->pipe_name,
00650 (unsigned int)cli->fnum,
00651 prhdr->pkt_type,
00652 expected_pkt_type));
00653 return NT_STATUS_INVALID_INFO_CLASS;
00654 }
00655
00656
00657
00658
00659
00660 if ((prhdr->pkt_type == RPC_BINDACK) && !(prhdr->flags & RPC_FLG_LAST)) {
00661 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
00662 "setting fragment first/last ON.\n"));
00663 prhdr->flags |= RPC_FLG_FIRST|RPC_FLG_LAST;
00664 }
00665
00666 return NT_STATUS_OK;
00667 }
00668
00669
00670
00671
00672
00673
00674
00675
00676 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
00677 {
00678 uint32 current_pdu_len = prs_data_size(current_pdu);
00679
00680 if (current_pdu_len < prhdr->frag_len) {
00681 return NT_STATUS_BUFFER_TOO_SMALL;
00682 }
00683
00684
00685 if (current_pdu_len == (uint32)prhdr->frag_len) {
00686 prs_mem_free(current_pdu);
00687 prs_init(current_pdu, 0, prs_get_mem_context(current_pdu), UNMARSHALL);
00688
00689 prs_give_memory(current_pdu, 0, 0, True);
00690 return NT_STATUS_OK;
00691 }
00692
00693
00694
00695
00696
00697
00698 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
00699 current_pdu_len - prhdr->frag_len);
00700
00701
00702 prs_set_offset(current_pdu, 0);
00703
00704
00705 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
00706 return NT_STATUS_BUFFER_TOO_SMALL;
00707 }
00708
00709 return NT_STATUS_OK;
00710 }
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738 static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli,
00739 prs_struct *data,
00740 prs_struct *rbuf,
00741 uint8 expected_pkt_type)
00742 {
00743 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
00744 char *rparam = NULL;
00745 uint32 rparam_len = 0;
00746 uint16 setup[2];
00747 char *pdata = prs_data_p(data);
00748 uint32 data_len = prs_offset(data);
00749 char *prdata = NULL;
00750 uint32 rdata_len = 0;
00751 uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : RPC_MAX_PDU_FRAG_LEN;
00752 uint32 current_rbuf_offset = 0;
00753 prs_struct current_pdu;
00754
00755 #ifdef DEVELOPER
00756
00757 SMB_ASSERT(data_len <= max_data);
00758 #endif
00759
00760
00761 prs_init(¤t_pdu, 0, prs_get_mem_context(rbuf), UNMARSHALL);
00762
00763
00764 setup[0] = TRANSACT_DCERPCCMD;
00765 setup[1] = cli->fnum;
00766
00767 DEBUG(5,("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x\n",
00768 cli->cli->desthost,
00769 cli->pipe_name,
00770 (unsigned int)cli->fnum ));
00771
00772
00773
00774
00775
00776
00777
00778 if (!cli_api_pipe(cli->cli, "\\PIPE\\",
00779 setup, 2, 0,
00780 NULL, 0, 0,
00781 pdata, data_len, max_data,
00782 &rparam, &rparam_len,
00783 &prdata, &rdata_len))
00784 {
00785 DEBUG(0, ("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x"
00786 "returned critical error. Error was %s\n",
00787 cli->cli->desthost,
00788 cli->pipe_name,
00789 (unsigned int)cli->fnum,
00790 cli_errstr(cli->cli)));
00791 ret = cli_get_nt_error(cli->cli);
00792 SAFE_FREE(rparam);
00793 SAFE_FREE(prdata);
00794 goto err;
00795 }
00796
00797
00798
00799 SAFE_FREE(rparam);
00800
00801 if (prdata == NULL) {
00802 DEBUG(3,("rpc_api_pipe: Remote machine %s pipe %s "
00803 "fnum 0x%x failed to return data.\n",
00804 cli->cli->desthost,
00805 cli->pipe_name,
00806 (unsigned int)cli->fnum));
00807
00808 prs_mem_free(¤t_pdu);
00809 return NT_STATUS_OK;
00810 }
00811
00812
00813
00814
00815
00816 prs_give_memory(¤t_pdu, prdata, rdata_len, True);
00817
00818
00819 SMB_ASSERT(UNMARSHALLING(rbuf));
00820 SMB_ASSERT(prs_data_size(rbuf) == 0);
00821
00822
00823 prs_give_memory(rbuf, 0, 0, True);
00824
00825 while(1) {
00826 RPC_HDR rhdr;
00827 char *ret_data;
00828 uint32 ret_data_len;
00829
00830
00831 ret = cli_pipe_get_current_pdu(cli, &rhdr, ¤t_pdu);
00832 if (!NT_STATUS_IS_OK(ret)) {
00833 goto err;
00834 }
00835
00836
00837
00838
00839 ret = cli_pipe_validate_current_pdu(cli, &rhdr, ¤t_pdu, expected_pkt_type,
00840 &ret_data, &ret_data_len, rbuf);
00841
00842 DEBUG(10,("rpc_api_pipe: got PDU len of %u at offset %u\n",
00843 prs_data_size(¤t_pdu), current_rbuf_offset ));
00844
00845 if (!NT_STATUS_IS_OK(ret)) {
00846 goto err;
00847 }
00848
00849 if ((rhdr.flags & RPC_FLG_FIRST)) {
00850 if (rhdr.pack_type[0] == 0) {
00851
00852 DEBUG(10,("rpc_api_pipe: On machine %s pipe %s fnum 0x%x "
00853 "PDU data format is big-endian.\n",
00854 cli->cli->desthost,
00855 cli->pipe_name,
00856 (unsigned int)cli->fnum));
00857
00858 prs_set_endian_data(rbuf, RPC_BIG_ENDIAN);
00859 } else {
00860
00861 if (current_pdu.bigendian_data != rbuf->bigendian_data) {
00862 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to %s\n",
00863 rbuf->bigendian_data ? "big" : "little",
00864 current_pdu.bigendian_data ? "big" : "little" ));
00865 ret = NT_STATUS_INVALID_PARAMETER;
00866 goto err;
00867 }
00868 }
00869 }
00870
00871
00872 if (!prs_force_grow(rbuf, ret_data_len)) {
00873 ret = NT_STATUS_NO_MEMORY;
00874 goto err;
00875 }
00876 memcpy(prs_data_p(rbuf)+current_rbuf_offset, ret_data, (size_t)ret_data_len);
00877 current_rbuf_offset += ret_data_len;
00878
00879
00880 ret = cli_pipe_reset_current_pdu(cli, &rhdr, ¤t_pdu);
00881 if (!NT_STATUS_IS_OK(ret)) {
00882 goto err;
00883 }
00884
00885 if (rhdr.flags & RPC_FLG_LAST) {
00886 break;
00887 }
00888 }
00889
00890 DEBUG(10,("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x returned %u bytes.\n",
00891 cli->cli->desthost,
00892 cli->pipe_name,
00893 (unsigned int)cli->fnum,
00894 (unsigned int)prs_data_size(rbuf) ));
00895
00896 prs_mem_free(¤t_pdu);
00897 return NT_STATUS_OK;
00898
00899 err:
00900
00901 prs_mem_free(¤t_pdu);
00902 prs_mem_free(rbuf);
00903 return ret;
00904 }
00905
00906
00907
00908
00909
00910 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
00911 enum pipe_auth_level auth_level,
00912 RPC_HDR_AUTH *pauth_out,
00913 prs_struct *auth_data)
00914 {
00915 #ifdef HAVE_KRB5
00916 int ret;
00917 struct kerberos_auth_struct *a = cli->auth.a_u.kerberos_auth;
00918 DATA_BLOB tkt = data_blob(NULL, 0);
00919 DATA_BLOB tkt_wrapped = data_blob(NULL, 0);
00920
00921
00922 init_rpc_hdr_auth(pauth_out, RPC_KRB5_AUTH_TYPE, (int)auth_level, 0, 1);
00923
00924 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
00925 a->service_principal ));
00926
00927
00928
00929 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
00930 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL);
00931
00932 if (ret) {
00933 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
00934 "failed with %s\n",
00935 a->service_principal,
00936 error_message(ret) ));
00937
00938 data_blob_free(&tkt);
00939 prs_mem_free(auth_data);
00940 return NT_STATUS_INVALID_PARAMETER;
00941 }
00942
00943
00944 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
00945
00946 data_blob_free(&tkt);
00947
00948
00949 if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
00950 data_blob_free(&tkt_wrapped);
00951 prs_mem_free(auth_data);
00952 return NT_STATUS_NO_MEMORY;
00953 }
00954
00955 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
00956 dump_data(5, (const char *)tkt_wrapped.data, tkt_wrapped.length);
00957
00958 data_blob_free(&tkt_wrapped);
00959 return NT_STATUS_OK;
00960 #else
00961 return NT_STATUS_INVALID_PARAMETER;
00962 #endif
00963 }
00964
00965
00966
00967
00968
00969 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
00970 enum pipe_auth_level auth_level,
00971 RPC_HDR_AUTH *pauth_out,
00972 prs_struct *auth_data)
00973 {
00974 NTSTATUS nt_status;
00975 DATA_BLOB null_blob = data_blob(NULL, 0);
00976 DATA_BLOB request = data_blob(NULL, 0);
00977 DATA_BLOB spnego_msg = data_blob(NULL, 0);
00978
00979
00980 init_rpc_hdr_auth(pauth_out, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
00981
00982 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
00983 nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state,
00984 null_blob,
00985 &request);
00986
00987 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
00988 data_blob_free(&request);
00989 prs_mem_free(auth_data);
00990 return nt_status;
00991 }
00992
00993
00994 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
00995
00996 data_blob_free(&request);
00997
00998
00999 if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
01000 data_blob_free(&spnego_msg);
01001 prs_mem_free(auth_data);
01002 return NT_STATUS_NO_MEMORY;
01003 }
01004
01005 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
01006 dump_data(5, (const char *)spnego_msg.data, spnego_msg.length);
01007
01008 data_blob_free(&spnego_msg);
01009 return NT_STATUS_OK;
01010 }
01011
01012
01013
01014
01015
01016 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
01017 enum pipe_auth_level auth_level,
01018 RPC_HDR_AUTH *pauth_out,
01019 prs_struct *auth_data)
01020 {
01021 NTSTATUS nt_status;
01022 DATA_BLOB null_blob = data_blob(NULL, 0);
01023 DATA_BLOB request = data_blob(NULL, 0);
01024
01025
01026 init_rpc_hdr_auth(pauth_out, RPC_NTLMSSP_AUTH_TYPE, (int)auth_level, 0, 1);
01027
01028 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
01029 nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state,
01030 null_blob,
01031 &request);
01032
01033 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
01034 data_blob_free(&request);
01035 prs_mem_free(auth_data);
01036 return nt_status;
01037 }
01038
01039
01040 if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
01041 data_blob_free(&request);
01042 prs_mem_free(auth_data);
01043 return NT_STATUS_NO_MEMORY;
01044 }
01045
01046 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
01047 dump_data(5, (const char *)request.data, request.length);
01048
01049 data_blob_free(&request);
01050 return NT_STATUS_OK;
01051 }
01052
01053
01054
01055
01056
01057 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
01058 enum pipe_auth_level auth_level,
01059 RPC_HDR_AUTH *pauth_out,
01060 prs_struct *auth_data)
01061 {
01062 RPC_AUTH_SCHANNEL_NEG schannel_neg;
01063
01064
01065 init_rpc_hdr_auth(pauth_out, RPC_SCHANNEL_AUTH_TYPE, (int)auth_level, 0, 1);
01066
01067
01068
01069 if (!cli->domain || !cli->domain[0]) {
01070 cli->domain = lp_workgroup();
01071 }
01072
01073 init_rpc_auth_schannel_neg(&schannel_neg, cli->domain, global_myname());
01074
01075
01076
01077
01078
01079 if(!smb_io_rpc_auth_schannel_neg("schannel_neg",
01080 &schannel_neg, auth_data, 0)) {
01081 DEBUG(0,("Failed to marshall RPC_AUTH_SCHANNEL_NEG.\n"));
01082 prs_mem_free(auth_data);
01083 return NT_STATUS_NO_MEMORY;
01084 }
01085
01086 return NT_STATUS_OK;
01087 }
01088
01089
01090
01091
01092
01093 static NTSTATUS create_bind_or_alt_ctx_internal(enum RPC_PKT_TYPE pkt_type,
01094 prs_struct *rpc_out,
01095 uint32 rpc_call_id,
01096 RPC_IFACE *abstract,
01097 RPC_IFACE *transfer,
01098 RPC_HDR_AUTH *phdr_auth,
01099 prs_struct *pauth_info)
01100 {
01101 RPC_HDR hdr;
01102 RPC_HDR_RB hdr_rb;
01103 RPC_CONTEXT rpc_ctx;
01104 uint16 auth_len = prs_offset(pauth_info);
01105 uint8 ss_padding_len = 0;
01106 uint16 frag_len = 0;
01107
01108
01109 init_rpc_context(&rpc_ctx, 0 , abstract, transfer);
01110
01111
01112 init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
01113
01114
01115 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
01116
01117
01118 if (auth_len) {
01119 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
01120 if (data_len % 8) {
01121 ss_padding_len = 8 - (data_len % 8);
01122 phdr_auth->auth_pad_len = ss_padding_len;
01123 }
01124 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
01125 }
01126
01127
01128 init_rpc_hdr(&hdr, pkt_type, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id, frag_len, auth_len);
01129
01130
01131 if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
01132 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
01133 return NT_STATUS_NO_MEMORY;
01134 }
01135
01136
01137 if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
01138 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
01139 return NT_STATUS_NO_MEMORY;
01140 }
01141
01142
01143
01144
01145
01146 if(auth_len != 0) {
01147 if (ss_padding_len) {
01148 char pad[8];
01149 memset(pad, '\0', 8);
01150 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
01151 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
01152 return NT_STATUS_NO_MEMORY;
01153 }
01154 }
01155
01156 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
01157 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
01158 return NT_STATUS_NO_MEMORY;
01159 }
01160
01161
01162 if(!prs_append_prs_data( rpc_out, pauth_info)) {
01163 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
01164 return NT_STATUS_NO_MEMORY;
01165 }
01166 }
01167
01168 return NT_STATUS_OK;
01169 }
01170
01171
01172
01173
01174
01175 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
01176 prs_struct *rpc_out,
01177 uint32 rpc_call_id,
01178 RPC_IFACE *abstract, RPC_IFACE *transfer,
01179 enum pipe_auth_type auth_type,
01180 enum pipe_auth_level auth_level)
01181 {
01182 RPC_HDR_AUTH hdr_auth;
01183 prs_struct auth_info;
01184 NTSTATUS ret = NT_STATUS_OK;
01185
01186 ZERO_STRUCT(hdr_auth);
01187 prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL);
01188
01189 switch (auth_type) {
01190 case PIPE_AUTH_TYPE_SCHANNEL:
01191 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
01192 if (!NT_STATUS_IS_OK(ret)) {
01193 prs_mem_free(&auth_info);
01194 return ret;
01195 }
01196 break;
01197
01198 case PIPE_AUTH_TYPE_NTLMSSP:
01199 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
01200 if (!NT_STATUS_IS_OK(ret)) {
01201 prs_mem_free(&auth_info);
01202 return ret;
01203 }
01204 break;
01205
01206 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
01207 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
01208 if (!NT_STATUS_IS_OK(ret)) {
01209 prs_mem_free(&auth_info);
01210 return ret;
01211 }
01212 break;
01213
01214 case PIPE_AUTH_TYPE_KRB5:
01215 ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
01216 if (!NT_STATUS_IS_OK(ret)) {
01217 prs_mem_free(&auth_info);
01218 return ret;
01219 }
01220 break;
01221
01222 case PIPE_AUTH_TYPE_NONE:
01223 break;
01224
01225 default:
01226
01227 return NT_STATUS_INVALID_INFO_CLASS;
01228 }
01229
01230 ret = create_bind_or_alt_ctx_internal(RPC_BIND,
01231 rpc_out,
01232 rpc_call_id,
01233 abstract,
01234 transfer,
01235 &hdr_auth,
01236 &auth_info);
01237
01238 prs_mem_free(&auth_info);
01239 return ret;
01240 }
01241
01242
01243
01244
01245
01246 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
01247 RPC_HDR *phdr,
01248 uint32 ss_padding_len,
01249 prs_struct *outgoing_pdu)
01250 {
01251 RPC_HDR_AUTH auth_info;
01252 NTSTATUS status;
01253 DATA_BLOB auth_blob = data_blob(NULL, 0);
01254 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
01255
01256 if (!cli->auth.a_u.ntlmssp_state) {
01257 return NT_STATUS_INVALID_PARAMETER;
01258 }
01259
01260
01261 init_rpc_hdr_auth(&auth_info,
01262 map_pipe_auth_type_to_rpc_auth_type(cli->auth.auth_type),
01263 cli->auth.auth_level,
01264 ss_padding_len,
01265 1 );
01266
01267 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
01268 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
01269 data_blob_free(&auth_blob);
01270 return NT_STATUS_NO_MEMORY;
01271 }
01272
01273 switch (cli->auth.auth_level) {
01274 case PIPE_AUTH_LEVEL_PRIVACY:
01275
01276 status = ntlmssp_seal_packet(cli->auth.a_u.ntlmssp_state,
01277 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
01278 data_and_pad_len,
01279 (unsigned char *)prs_data_p(outgoing_pdu),
01280 (size_t)prs_offset(outgoing_pdu),
01281 &auth_blob);
01282 if (!NT_STATUS_IS_OK(status)) {
01283 data_blob_free(&auth_blob);
01284 return status;
01285 }
01286 break;
01287
01288 case PIPE_AUTH_LEVEL_INTEGRITY:
01289
01290 status = ntlmssp_sign_packet(cli->auth.a_u.ntlmssp_state,
01291 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
01292 data_and_pad_len,
01293 (unsigned char *)prs_data_p(outgoing_pdu),
01294 (size_t)prs_offset(outgoing_pdu),
01295 &auth_blob);
01296 if (!NT_STATUS_IS_OK(status)) {
01297 data_blob_free(&auth_blob);
01298 return status;
01299 }
01300 break;
01301
01302 default:
01303
01304 smb_panic("bad auth level");
01305
01306 return NT_STATUS_INVALID_PARAMETER;
01307 }
01308
01309
01310
01311 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
01312 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
01313 (unsigned int)NTLMSSP_SIG_SIZE));
01314 data_blob_free(&auth_blob);
01315 return NT_STATUS_NO_MEMORY;
01316 }
01317
01318 data_blob_free(&auth_blob);
01319 return NT_STATUS_OK;
01320 }
01321
01322
01323
01324
01325
01326 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
01327 RPC_HDR *phdr,
01328 uint32 ss_padding_len,
01329 prs_struct *outgoing_pdu)
01330 {
01331 RPC_HDR_AUTH auth_info;
01332 RPC_AUTH_SCHANNEL_CHK verf;
01333 struct schannel_auth_struct *sas = cli->auth.a_u.schannel_auth;
01334 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
01335 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
01336
01337 if (!sas) {
01338 return NT_STATUS_INVALID_PARAMETER;
01339 }
01340
01341
01342 init_rpc_hdr_auth(&auth_info,
01343 map_pipe_auth_type_to_rpc_auth_type(cli->auth.auth_type),
01344 cli->auth.auth_level,
01345 ss_padding_len,
01346 1 );
01347
01348 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
01349 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
01350 return NT_STATUS_NO_MEMORY;
01351 }
01352
01353 switch (cli->auth.auth_level) {
01354 case PIPE_AUTH_LEVEL_PRIVACY:
01355 case PIPE_AUTH_LEVEL_INTEGRITY:
01356 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
01357 sas->seq_num));
01358
01359 schannel_encode(sas,
01360 cli->auth.auth_level,
01361 SENDER_IS_INITIATOR,
01362 &verf,
01363 data_p,
01364 data_and_pad_len);
01365
01366 sas->seq_num++;
01367 break;
01368
01369 default:
01370
01371 smb_panic("bad auth level");
01372
01373 return NT_STATUS_INVALID_PARAMETER;
01374 }
01375
01376
01377 smb_io_rpc_auth_schannel_chk("",
01378 RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
01379 &verf,
01380 outgoing_pdu,
01381 0);
01382
01383 return NT_STATUS_OK;
01384 }
01385
01386
01387
01388
01389
01390
01391 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
01392 uint32 data_left,
01393 uint16 *p_frag_len,
01394 uint16 *p_auth_len,
01395 uint32 *p_ss_padding)
01396 {
01397 uint32 data_space, data_len;
01398
01399 switch (cli->auth.auth_level) {
01400 case PIPE_AUTH_LEVEL_NONE:
01401 case PIPE_AUTH_LEVEL_CONNECT:
01402 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
01403 data_len = MIN(data_space, data_left);
01404 *p_ss_padding = 0;
01405 *p_auth_len = 0;
01406 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
01407 return data_len;
01408
01409 case PIPE_AUTH_LEVEL_INTEGRITY:
01410 case PIPE_AUTH_LEVEL_PRIVACY:
01411
01412 switch(cli->auth.auth_type) {
01413 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
01414 case PIPE_AUTH_TYPE_NTLMSSP:
01415 *p_auth_len = NTLMSSP_SIG_SIZE;
01416 break;
01417 case PIPE_AUTH_TYPE_SCHANNEL:
01418 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
01419 break;
01420 default:
01421 smb_panic("bad auth type");
01422 break;
01423 }
01424
01425 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
01426 RPC_HDR_AUTH_LEN - *p_auth_len;
01427
01428 data_len = MIN(data_space, data_left);
01429 if (data_len % 8) {
01430 *p_ss_padding = 8 - (data_len % 8);
01431 }
01432 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN +
01433 data_len + *p_ss_padding +
01434 RPC_HDR_AUTH_LEN + *p_auth_len;
01435 return data_len;
01436
01437 default:
01438 smb_panic("bad auth level");
01439
01440 return 0;
01441 }
01442 }
01443
01444
01445
01446
01447
01448
01449
01450
01451 NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli,
01452 uint8 op_num,
01453 prs_struct *in_data,
01454 prs_struct *out_data)
01455 {
01456 NTSTATUS ret;
01457 uint32 data_left = prs_offset(in_data);
01458 uint32 alloc_hint = prs_offset(in_data);
01459 uint32 data_sent_thistime = 0;
01460 uint32 current_data_offset = 0;
01461 uint32 call_id = get_rpc_call_id();
01462 char pad[8];
01463 prs_struct outgoing_pdu;
01464
01465 memset(pad, '\0', 8);
01466
01467 if (cli->max_xmit_frag < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
01468
01469 return NT_STATUS_INVALID_PARAMETER;
01470 }
01471
01472 prs_init(&outgoing_pdu, cli->max_xmit_frag, prs_get_mem_context(in_data), MARSHALL);
01473
01474 while (1) {
01475 RPC_HDR hdr;
01476 RPC_HDR_REQ hdr_req;
01477 uint16 auth_len = 0;
01478 uint16 frag_len = 0;
01479 uint8 flags = 0;
01480 uint32 ss_padding = 0;
01481
01482 data_sent_thistime = calculate_data_len_tosend(cli, data_left,
01483 &frag_len, &auth_len, &ss_padding);
01484
01485 if (current_data_offset == 0) {
01486 flags = RPC_FLG_FIRST;
01487 }
01488
01489 if (data_sent_thistime == data_left) {
01490 flags |= RPC_FLG_LAST;
01491 }
01492
01493
01494 init_rpc_hdr(&hdr, RPC_REQUEST, flags, call_id, frag_len, auth_len);
01495
01496 if(!smb_io_rpc_hdr("hdr ", &hdr, &outgoing_pdu, 0)) {
01497 prs_mem_free(&outgoing_pdu);
01498 return NT_STATUS_NO_MEMORY;
01499 }
01500
01501
01502 init_rpc_hdr_req(&hdr_req, alloc_hint, op_num);
01503
01504 if(!smb_io_rpc_hdr_req("hdr_req", &hdr_req, &outgoing_pdu, 0)) {
01505 prs_mem_free(&outgoing_pdu);
01506 return NT_STATUS_NO_MEMORY;
01507 }
01508
01509
01510 if (!prs_append_some_prs_data(&outgoing_pdu, in_data, current_data_offset, data_sent_thistime)) {
01511 prs_mem_free(&outgoing_pdu);
01512 return NT_STATUS_NO_MEMORY;
01513 }
01514
01515
01516 if (ss_padding) {
01517 if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding)) {
01518 prs_mem_free(&outgoing_pdu);
01519 return NT_STATUS_NO_MEMORY;
01520 }
01521 }
01522
01523
01524 if (auth_len) {
01525 switch (cli->auth.auth_type) {
01526 case PIPE_AUTH_TYPE_NONE:
01527 break;
01528 case PIPE_AUTH_TYPE_NTLMSSP:
01529 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
01530 ret = add_ntlmssp_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
01531 if (!NT_STATUS_IS_OK(ret)) {
01532 prs_mem_free(&outgoing_pdu);
01533 return ret;
01534 }
01535 break;
01536 case PIPE_AUTH_TYPE_SCHANNEL:
01537 ret = add_schannel_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
01538 if (!NT_STATUS_IS_OK(ret)) {
01539 prs_mem_free(&outgoing_pdu);
01540 return ret;
01541 }
01542 break;
01543 default:
01544 smb_panic("bad auth type");
01545 break;
01546 }
01547 }
01548
01549
01550 if (flags & RPC_FLG_LAST) {
01551
01552 ret = rpc_api_pipe(cli, &outgoing_pdu, out_data, RPC_RESPONSE);
01553 prs_mem_free(&outgoing_pdu);
01554
01555
01556 if (DEBUGLEVEL >= 50) {
01557 pstring dump_name;
01558
01559 slprintf(dump_name, sizeof(dump_name) - 1, "%s/reply_%s_%d",
01560 dyn_LOGFILEBASE, cli->pipe_name, op_num);
01561 prs_dump(dump_name, op_num, out_data);
01562 }
01563
01564 return ret;
01565 } else {
01566
01567 ssize_t num_written = cli_write(cli->cli, cli->fnum, 8,
01568 prs_data_p(&outgoing_pdu),
01569 (off_t)0,
01570 (size_t)hdr.frag_len);
01571
01572 if (num_written != hdr.frag_len) {
01573 prs_mem_free(&outgoing_pdu);
01574 return cli_get_nt_error(cli->cli);
01575 }
01576 }
01577
01578 current_data_offset += data_sent_thistime;
01579 data_left -= data_sent_thistime;
01580
01581
01582 if (!prs_set_offset(&outgoing_pdu, 0)) {
01583 prs_mem_free(&outgoing_pdu);
01584 return NT_STATUS_NO_MEMORY;
01585 }
01586 }
01587 }
01588 #if 0
01589
01590
01591
01592
01593 static BOOL rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
01594 const char *pipe_name, uint16 device_state)
01595 {
01596 BOOL state_set = False;
01597 char param[2];
01598 uint16 setup[2];
01599 char *rparam = NULL;
01600 char *rdata = NULL;
01601 uint32 rparam_len, rdata_len;
01602
01603 if (pipe_name == NULL)
01604 return False;
01605
01606 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
01607 cli->fnum, pipe_name, device_state));
01608
01609
01610 SSVAL(param, 0, device_state);
01611
01612
01613 setup[0] = 0x0001;
01614 setup[1] = cli->fnum;
01615
01616
01617 if (cli_api_pipe(cli->cli, "\\PIPE\\",
01618 setup, 2, 0,
01619 param, 2, 0,
01620 NULL, 0, 1024,
01621 &rparam, &rparam_len,
01622 &rdata, &rdata_len))
01623 {
01624 DEBUG(5, ("Set Handle state: return OK\n"));
01625 state_set = True;
01626 }
01627
01628 SAFE_FREE(rparam);
01629 SAFE_FREE(rdata);
01630
01631 return state_set;
01632 }
01633 #endif
01634
01635
01636
01637
01638
01639 static BOOL valid_pipe_name(const int pipe_idx, RPC_IFACE *abstract, RPC_IFACE *transfer)
01640 {
01641 if ( pipe_idx >= PI_MAX_PIPES ) {
01642 DEBUG(0,("valid_pipe_name: Programmer error! Invalid pipe index [%d]\n",
01643 pipe_idx));
01644 return False;
01645 }
01646
01647 DEBUG(5,("Bind Abstract Syntax: "));
01648 dump_data(5, (char*)&pipe_names[pipe_idx].abstr_syntax,
01649 sizeof(pipe_names[pipe_idx].abstr_syntax));
01650 DEBUG(5,("Bind Transfer Syntax: "));
01651 dump_data(5, (char*)&pipe_names[pipe_idx].trans_syntax,
01652 sizeof(pipe_names[pipe_idx].trans_syntax));
01653
01654
01655
01656 *transfer = pipe_names[pipe_idx].trans_syntax;
01657 *abstract = pipe_names[pipe_idx].abstr_syntax;
01658
01659 return True;
01660 }
01661
01662
01663
01664
01665
01666 static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFACE *transfer)
01667 {
01668 if ( hdr_ba->addr.len == 0) {
01669 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
01670 }
01671
01672 # if 0
01673 if ( !strequal(hdr_ba->addr.str, pipe_names[pipe_idx].client_pipe) &&
01674 !strequal(hdr_ba->addr.str, pipe_names[pipe_idx].server_pipe) )
01675 {
01676 DEBUG(4,("bind_rpc_pipe: pipe_name %s != expected pipe %s. oh well!\n",
01677 pipe_names[i].server_pipe ,hdr_ba->addr.str));
01678 return False;
01679 }
01680
01681 DEBUG(5,("bind_rpc_pipe: server pipe_name found: %s\n", pipe_names[i].server_pipe ));
01682
01683 if (pipe_names[pipe_idx].server_pipe == NULL) {
01684 DEBUG(2,("bind_rpc_pipe: pipe name %s unsupported\n", hdr_ba->addr.str));
01685 return False;
01686 }
01687 #endif
01688
01689
01690 if ((hdr_ba->transfer.version != transfer->version) ||
01691 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
01692 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
01693 return False;
01694 }
01695
01696 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
01697 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
01698 hdr_ba->res.num_results, hdr_ba->res.reason));
01699 }
01700
01701 DEBUG(5,("check_bind_response: accepted!\n"));
01702 return True;
01703 }
01704
01705
01706
01707
01708
01709
01710
01711
01712 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
01713 uint32 rpc_call_id,
01714 enum pipe_auth_type auth_type,
01715 enum pipe_auth_level auth_level,
01716 DATA_BLOB *pauth_blob,
01717 prs_struct *rpc_out)
01718 {
01719 RPC_HDR hdr;
01720 RPC_HDR_AUTH hdr_auth;
01721 uint32 pad = 0;
01722
01723
01724 init_rpc_hdr(&hdr, RPC_AUTH3, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id,
01725 RPC_HEADER_LEN + 4 + RPC_HDR_AUTH_LEN + pauth_blob->length,
01726 pauth_blob->length );
01727
01728
01729 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
01730 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
01731 return NT_STATUS_NO_MEMORY;
01732 }
01733
01734
01735
01736
01737
01738
01739
01740 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
01741 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
01742 return NT_STATUS_NO_MEMORY;
01743 }
01744
01745
01746 init_rpc_hdr_auth(&hdr_auth,
01747 map_pipe_auth_type_to_rpc_auth_type(auth_type),
01748 auth_level, 0, 1);
01749
01750 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
01751 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
01752 return NT_STATUS_NO_MEMORY;
01753 }
01754
01755
01756
01757
01758
01759 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
01760 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
01761 return NT_STATUS_NO_MEMORY;
01762 }
01763
01764 return NT_STATUS_OK;
01765 }
01766
01767
01768
01769
01770
01771 static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli,
01772 RPC_HDR *phdr,
01773 prs_struct *rbuf,
01774 uint32 rpc_call_id,
01775 enum pipe_auth_type auth_type,
01776 enum pipe_auth_level auth_level)
01777 {
01778 DATA_BLOB server_response = data_blob(NULL,0);
01779 DATA_BLOB client_reply = data_blob(NULL,0);
01780 RPC_HDR_AUTH hdr_auth;
01781 NTSTATUS nt_status;
01782 prs_struct rpc_out;
01783 ssize_t ret;
01784
01785 if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
01786 return NT_STATUS_INVALID_PARAMETER;
01787 }
01788
01789
01790 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
01791 return NT_STATUS_INVALID_PARAMETER;
01792 }
01793
01794 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
01795 return NT_STATUS_INVALID_PARAMETER;
01796 }
01797
01798
01799
01800 server_response = data_blob(NULL, phdr->auth_len);
01801 prs_copy_data_out((char *)server_response.data, rbuf, phdr->auth_len);
01802
01803 nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state,
01804 server_response,
01805 &client_reply);
01806
01807 if (!NT_STATUS_IS_OK(nt_status)) {
01808 DEBUG(0,("rpc_finish_auth3_bind: NTLMSSP update using server blob failed.\n"));
01809 data_blob_free(&server_response);
01810 return nt_status;
01811 }
01812
01813 prs_init(&rpc_out, 0, prs_get_mem_context(rbuf), MARSHALL);
01814
01815 nt_status = create_rpc_bind_auth3(cli, rpc_call_id,
01816 auth_type, auth_level,
01817 &client_reply, &rpc_out);
01818
01819 if (!NT_STATUS_IS_OK(nt_status)) {
01820 prs_mem_free(&rpc_out);
01821 data_blob_free(&client_reply);
01822 data_blob_free(&server_response);
01823 return nt_status;
01824 }
01825
01826
01827 ret = cli_write(cli->cli, cli->fnum, 0x8, prs_data_p(&rpc_out), 0,
01828 (size_t)prs_offset(&rpc_out));
01829
01830 if (ret != (ssize_t)prs_offset(&rpc_out)) {
01831 DEBUG(0,("rpc_send_auth_auth3: cli_write failed. Return was %d\n", (int)ret));
01832 prs_mem_free(&rpc_out);
01833 data_blob_free(&client_reply);
01834 data_blob_free(&server_response);
01835 return cli_get_nt_error(cli->cli);
01836 }
01837
01838 DEBUG(5,("rpc_send_auth_auth3: Remote machine %s pipe %s "
01839 "fnum 0x%x sent auth3 response ok.\n",
01840 cli->cli->desthost,
01841 cli->pipe_name,
01842 (unsigned int)cli->fnum));
01843
01844 prs_mem_free(&rpc_out);
01845 data_blob_free(&client_reply);
01846 data_blob_free(&server_response);
01847 return NT_STATUS_OK;
01848 }
01849
01850
01851
01852
01853
01854
01855 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
01856 RPC_IFACE *abstract,
01857 RPC_IFACE *transfer,
01858 enum pipe_auth_level auth_level,
01859 const DATA_BLOB *pauth_blob,
01860 prs_struct *rpc_out)
01861 {
01862 RPC_HDR_AUTH hdr_auth;
01863 prs_struct auth_info;
01864 NTSTATUS ret = NT_STATUS_OK;
01865
01866 ZERO_STRUCT(hdr_auth);
01867 prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL);
01868
01869
01870 init_rpc_hdr_auth(&hdr_auth, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
01871
01872 if (pauth_blob->length) {
01873 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
01874 prs_mem_free(&auth_info);
01875 return NT_STATUS_NO_MEMORY;
01876 }
01877 }
01878
01879 ret = create_bind_or_alt_ctx_internal(RPC_ALTCONT,
01880 rpc_out,
01881 rpc_call_id,
01882 abstract,
01883 transfer,
01884 &hdr_auth,
01885 &auth_info);
01886 prs_mem_free(&auth_info);
01887 return ret;
01888 }
01889
01890
01891
01892
01893
01894
01895 static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli,
01896 RPC_HDR *phdr,
01897 prs_struct *rbuf,
01898 uint32 rpc_call_id,
01899 RPC_IFACE *abstract,
01900 RPC_IFACE *transfer,
01901 enum pipe_auth_type auth_type,
01902 enum pipe_auth_level auth_level)
01903 {
01904 DATA_BLOB server_spnego_response = data_blob(NULL,0);
01905 DATA_BLOB server_ntlm_response = data_blob(NULL,0);
01906 DATA_BLOB client_reply = data_blob(NULL,0);
01907 DATA_BLOB tmp_blob = data_blob(NULL, 0);
01908 RPC_HDR_AUTH hdr_auth;
01909 NTSTATUS nt_status;
01910 prs_struct rpc_out;
01911
01912 if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
01913 return NT_STATUS_INVALID_PARAMETER;
01914 }
01915
01916
01917 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
01918 return NT_STATUS_INVALID_PARAMETER;
01919 }
01920
01921 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
01922 return NT_STATUS_INVALID_PARAMETER;
01923 }
01924
01925 server_spnego_response = data_blob(NULL, phdr->auth_len);
01926 prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
01927
01928
01929 if (!spnego_parse_challenge(server_spnego_response, &server_ntlm_response, &tmp_blob)) {
01930 data_blob_free(&server_spnego_response);
01931 data_blob_free(&server_ntlm_response);
01932 data_blob_free(&tmp_blob);
01933 return NT_STATUS_INVALID_PARAMETER;
01934 }
01935
01936
01937 data_blob_free(&server_spnego_response);
01938 data_blob_free(&tmp_blob);
01939
01940 nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state,
01941 server_ntlm_response,
01942 &client_reply);
01943
01944
01945 data_blob_free(&server_ntlm_response);
01946
01947 if (!NT_STATUS_IS_OK(nt_status)) {
01948 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update using server blob failed.\n"));
01949 data_blob_free(&client_reply);
01950 return nt_status;
01951 }
01952
01953
01954 tmp_blob = spnego_gen_auth(client_reply);
01955 data_blob_free(&client_reply);
01956 client_reply = tmp_blob;
01957 tmp_blob = data_blob(NULL,0);
01958
01959
01960 prs_init(&rpc_out, 0, prs_get_mem_context(rbuf), MARSHALL);
01961
01962 nt_status = create_rpc_alter_context(rpc_call_id,
01963 abstract,
01964 transfer,
01965 auth_level,
01966 &client_reply,
01967 &rpc_out);
01968
01969 data_blob_free(&client_reply);
01970
01971 if (!NT_STATUS_IS_OK(nt_status)) {
01972 prs_mem_free(&rpc_out);
01973 return nt_status;
01974 }
01975
01976
01977 prs_mem_free(rbuf);
01978 prs_init(rbuf, 0, cli->cli->mem_ctx, UNMARSHALL);
01979
01980 nt_status = rpc_api_pipe(cli, &rpc_out, rbuf, RPC_ALTCONTRESP);
01981 if (!NT_STATUS_IS_OK(nt_status)) {
01982 prs_mem_free(&rpc_out);
01983 return nt_status;
01984 }
01985
01986 prs_mem_free(&rpc_out);
01987
01988
01989 if(!smb_io_rpc_hdr("rpc_hdr ", phdr, rbuf, 0)) {
01990 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: Failed to unmarshall RPC_HDR.\n"));
01991 return NT_STATUS_BUFFER_TOO_SMALL;
01992 }
01993
01994 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
01995 return NT_STATUS_INVALID_PARAMETER;
01996 }
01997
01998 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
01999 return NT_STATUS_INVALID_PARAMETER;
02000 }
02001
02002 server_spnego_response = data_blob(NULL, phdr->auth_len);
02003 prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
02004
02005
02006 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK, &tmp_blob)) {
02007 data_blob_free(&server_spnego_response);
02008 data_blob_free(&tmp_blob);
02009 return NT_STATUS_INVALID_PARAMETER;
02010 }
02011
02012 data_blob_free(&server_spnego_response);
02013 data_blob_free(&tmp_blob);
02014
02015 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
02016 "remote machine %s pipe %s fnum 0x%x.\n",
02017 cli->cli->desthost,
02018 cli->pipe_name,
02019 (unsigned int)cli->fnum));
02020
02021 return NT_STATUS_OK;
02022 }
02023
02024
02025
02026
02027
02028 static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
02029 enum pipe_auth_type auth_type,
02030 enum pipe_auth_level auth_level)
02031 {
02032 RPC_HDR hdr;
02033 RPC_HDR_BA hdr_ba;
02034 RPC_IFACE abstract;
02035 RPC_IFACE transfer;
02036 prs_struct rpc_out;
02037 prs_struct rbuf;
02038 uint32 rpc_call_id;
02039 NTSTATUS status;
02040
02041 DEBUG(5,("Bind RPC Pipe[%x]: %s auth_type %u, auth_level %u\n",
02042 (unsigned int)cli->fnum,
02043 cli->pipe_name,
02044 (unsigned int)auth_type,
02045 (unsigned int)auth_level ));
02046
02047 if (!valid_pipe_name(cli->pipe_idx, &abstract, &transfer)) {
02048 return NT_STATUS_INVALID_PARAMETER;
02049 }
02050
02051 prs_init(&rpc_out, 0, cli->cli->mem_ctx, MARSHALL);
02052
02053 rpc_call_id = get_rpc_call_id();
02054
02055
02056 status = create_rpc_bind_req(cli, &rpc_out, rpc_call_id,
02057 &abstract, &transfer,
02058 auth_type,
02059 auth_level);
02060
02061 if (!NT_STATUS_IS_OK(status)) {
02062 prs_mem_free(&rpc_out);
02063 return status;
02064 }
02065
02066
02067 prs_init(&rbuf, 0, cli->cli->mem_ctx, UNMARSHALL);
02068
02069
02070 status = rpc_api_pipe(cli, &rpc_out, &rbuf, RPC_BINDACK);
02071 if (!NT_STATUS_IS_OK(status)) {
02072 prs_mem_free(&rpc_out);
02073 return status;
02074 }
02075
02076 prs_mem_free(&rpc_out);
02077
02078 DEBUG(3,("rpc_pipe_bind: Remote machine %s pipe %s "
02079 "fnum 0x%x bind request returned ok.\n",
02080 cli->cli->desthost,
02081 cli->pipe_name,
02082 (unsigned int)cli->fnum));
02083
02084
02085 if(!smb_io_rpc_hdr("hdr" , &hdr, &rbuf, 0)) {
02086 DEBUG(0,("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
02087 prs_mem_free(&rbuf);
02088 return NT_STATUS_BUFFER_TOO_SMALL;
02089 }
02090
02091 if(!smb_io_rpc_hdr_ba("", &hdr_ba, &rbuf, 0)) {
02092 DEBUG(0,("rpc_pipe_bind: Failed to unmarshall RPC_HDR_BA.\n"));
02093 prs_mem_free(&rbuf);
02094 return NT_STATUS_BUFFER_TOO_SMALL;
02095 }
02096
02097 if(!check_bind_response(&hdr_ba, cli->pipe_idx, &transfer)) {
02098 DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n"));
02099 prs_mem_free(&rbuf);
02100 return NT_STATUS_BUFFER_TOO_SMALL;
02101 }
02102
02103 cli->max_xmit_frag = hdr_ba.bba.max_tsize;
02104 cli->max_recv_frag = hdr_ba.bba.max_rsize;
02105
02106
02107 switch(auth_type) {
02108
02109 case PIPE_AUTH_TYPE_NONE:
02110 case PIPE_AUTH_TYPE_SCHANNEL:
02111
02112 break;
02113
02114 case PIPE_AUTH_TYPE_NTLMSSP:
02115
02116 status = rpc_finish_auth3_bind(cli, &hdr, &rbuf, rpc_call_id,
02117 auth_type, auth_level);
02118 if (!NT_STATUS_IS_OK(status)) {
02119 prs_mem_free(&rbuf);
02120 return status;
02121 }
02122 break;
02123
02124 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
02125
02126 status = rpc_finish_spnego_ntlmssp_bind(cli, &hdr, &rbuf, rpc_call_id,
02127 &abstract, &transfer,
02128 auth_type, auth_level);
02129 if (!NT_STATUS_IS_OK(status)) {
02130 prs_mem_free(&rbuf);
02131 return status;
02132 }
02133 break;
02134
02135 case PIPE_AUTH_TYPE_KRB5:
02136
02137
02138 default:
02139 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
02140 (unsigned int)auth_type ));
02141 prs_mem_free(&rbuf);
02142 return NT_STATUS_INVALID_INFO_CLASS;
02143 }
02144
02145
02146 if (auth_type == PIPE_AUTH_TYPE_NTLMSSP || auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
02147 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
02148 if (!(cli->auth.a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
02149 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP signing and server refused.\n"));
02150 prs_mem_free(&rbuf);
02151 return NT_STATUS_INVALID_PARAMETER;
02152 }
02153 }
02154 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
02155 if (!(cli->auth.a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
02156 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP sealing and server refused.\n"));
02157 prs_mem_free(&rbuf);
02158 return NT_STATUS_INVALID_PARAMETER;
02159 }
02160 }
02161 }
02162
02163
02164
02165 cli->auth.auth_type = auth_type;
02166 cli->auth.auth_level = auth_level;
02167
02168 prs_mem_free(&rbuf);
02169 return NT_STATUS_OK;
02170 }
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185 static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
02186 {
02187 TALLOC_CTX *mem_ctx;
02188 struct rpc_pipe_client *result;
02189 int fnum;
02190
02191 *perr = NT_STATUS_NO_MEMORY;
02192
02193
02194
02195 if ( !cli ) {
02196 *perr = NT_STATUS_INVALID_HANDLE;
02197 return NULL;
02198 }
02199
02200
02201 SMB_ASSERT((pipe_idx >= 0) && (pipe_idx < PI_MAX_PIPES));
02202
02203 mem_ctx = talloc_init("struct rpc_pipe_client");
02204 if (mem_ctx == NULL) {
02205 return NULL;
02206 }
02207
02208 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
02209 if (result == NULL) {
02210 return NULL;
02211 }
02212
02213 result->mem_ctx = mem_ctx;
02214
02215 result->pipe_name = cli_get_pipe_name(pipe_idx);
02216
02217 fnum = cli_nt_create(cli, result->pipe_name, DESIRED_ACCESS_PIPE);
02218
02219 if (fnum == -1) {
02220 DEBUG(1,("cli_rpc_pipe_open: cli_nt_create failed on pipe %s "
02221 "to machine %s. Error was %s\n",
02222 result->pipe_name, cli->desthost,
02223 cli_errstr(cli)));
02224 *perr = cli_get_nt_error(cli);
02225 talloc_destroy(result->mem_ctx);
02226 return NULL;
02227 }
02228
02229 result->fnum = fnum;
02230 result->cli = cli;
02231 result->pipe_idx = pipe_idx;
02232 result->auth.auth_type = PIPE_AUTH_TYPE_NONE;
02233 result->auth.auth_level = PIPE_AUTH_LEVEL_NONE;
02234
02235 if (pipe_idx == PI_NETLOGON) {
02236
02237 result->dc = TALLOC_ZERO_P(mem_ctx, struct dcinfo);
02238 if (result->dc == NULL) {
02239 talloc_destroy(result->mem_ctx);
02240 return NULL;
02241 }
02242 }
02243
02244 DLIST_ADD(cli->pipe_list, result);
02245 *perr = NT_STATUS_OK;
02246
02247 return result;
02248 }
02249
02250
02251
02252
02253
02254 struct rpc_pipe_client *cli_rpc_pipe_open_noauth(struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
02255 {
02256 struct rpc_pipe_client *result;
02257
02258 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
02259 if (result == NULL) {
02260 return NULL;
02261 }
02262
02263 *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_NONE, PIPE_AUTH_LEVEL_NONE);
02264 if (!NT_STATUS_IS_OK(*perr)) {
02265 int lvl = 0;
02266 if (pipe_idx == PI_LSARPC_DS) {
02267
02268
02269 lvl = 3;
02270 }
02271 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe %s failed with error %s\n",
02272 cli_get_pipe_name(pipe_idx), nt_errstr(*perr) ));
02273 cli_rpc_pipe_close(result);
02274 return NULL;
02275 }
02276
02277 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine %s and bound anonymously.\n",
02278 result->pipe_name, cli->desthost ));
02279
02280 return result;
02281 }
02282
02283
02284
02285
02286
02287 static void cli_ntlmssp_auth_free(struct cli_pipe_auth_data *auth)
02288 {
02289 if (auth->a_u.ntlmssp_state) {
02290 ntlmssp_end(&auth->a_u.ntlmssp_state);
02291 auth->a_u.ntlmssp_state = NULL;
02292 }
02293 }
02294
02295
02296
02297
02298
02299 static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
02300 int pipe_idx,
02301 enum pipe_auth_type auth_type,
02302 enum pipe_auth_level auth_level,
02303 const char *domain,
02304 const char *username,
02305 const char *password,
02306 NTSTATUS *perr)
02307 {
02308 struct rpc_pipe_client *result;
02309 NTLMSSP_STATE *ntlmssp_state = NULL;
02310
02311 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
02312 if (result == NULL) {
02313 return NULL;
02314 }
02315
02316 result->auth.cli_auth_data_free_func = cli_ntlmssp_auth_free;
02317
02318 result->domain = domain;
02319 result->user_name = username;
02320 pwd_set_cleartext(&result->pwd, password);
02321
02322 *perr = ntlmssp_client_start(&ntlmssp_state);
02323 if (!NT_STATUS_IS_OK(*perr)) {
02324 goto err;
02325 }
02326
02327 result->auth.a_u.ntlmssp_state = ntlmssp_state;
02328
02329 *perr = ntlmssp_set_username(ntlmssp_state, cli->user_name);
02330 if (!NT_STATUS_IS_OK(*perr)) {
02331 goto err;
02332 }
02333
02334 *perr = ntlmssp_set_domain(ntlmssp_state, cli->domain);
02335 if (!NT_STATUS_IS_OK(*perr)) {
02336 goto err;
02337 }
02338
02339 if (cli->pwd.null_pwd) {
02340 *perr = ntlmssp_set_password(ntlmssp_state, NULL);
02341 if (!NT_STATUS_IS_OK(*perr)) {
02342 goto err;
02343 }
02344 } else {
02345 *perr = ntlmssp_set_password(ntlmssp_state, password);
02346 if (!NT_STATUS_IS_OK(*perr)) {
02347 goto err;
02348 }
02349 }
02350
02351
02352 ntlmssp_state->neg_flags &= ~(NTLMSSP_NEGOTIATE_SIGN|NTLMSSP_NEGOTIATE_SEAL);
02353
02354 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
02355 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
02356 } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
02357 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
02358 }
02359
02360 *perr = rpc_pipe_bind(result, auth_type, auth_level);
02361 if (!NT_STATUS_IS_OK(*perr)) {
02362 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
02363 nt_errstr(*perr) ));
02364 goto err;
02365 }
02366
02367 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
02368 "machine %s and bound NTLMSSP as user %s\\%s.\n",
02369 result->pipe_name, cli->desthost,
02370 domain, username ));
02371
02372 return result;
02373
02374 err:
02375
02376 cli_rpc_pipe_close(result);
02377 return NULL;
02378 }
02379
02380
02381
02382
02383
02384
02385 struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
02386 int pipe_idx,
02387 enum pipe_auth_level auth_level,
02388 const char *domain,
02389 const char *username,
02390 const char *password,
02391 NTSTATUS *perr)
02392 {
02393 return cli_rpc_pipe_open_ntlmssp_internal(cli,
02394 pipe_idx,
02395 PIPE_AUTH_TYPE_NTLMSSP,
02396 auth_level,
02397 domain,
02398 username,
02399 password,
02400 perr);
02401 }
02402
02403
02404
02405
02406
02407
02408 struct rpc_pipe_client *cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
02409 int pipe_idx,
02410 enum pipe_auth_level auth_level,
02411 const char *domain,
02412 const char *username,
02413 const char *password,
02414 NTSTATUS *perr)
02415 {
02416 return cli_rpc_pipe_open_ntlmssp_internal(cli,
02417 pipe_idx,
02418 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
02419 auth_level,
02420 domain,
02421 username,
02422 password,
02423 perr);
02424 }
02425
02426
02427
02428
02429 static BOOL get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
02430 struct cli_state *cli,
02431 const char *domain,
02432 uint32 *pneg_flags,
02433 NTSTATUS *perr)
02434 {
02435 uint32 sec_chan_type = 0;
02436 unsigned char machine_pwd[16];
02437 const char *machine_account;
02438
02439
02440 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
02441 &sec_chan_type))
02442 {
02443 DEBUG(0, ("get_schannel_session_key: could not fetch "
02444 "trust account password for domain '%s'\n",
02445 domain));
02446 *perr = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
02447 return False;
02448 }
02449
02450 *perr = rpccli_netlogon_setup_creds(netlogon_pipe,
02451 cli->desthost,
02452 domain,
02453 global_myname(),
02454 machine_account,
02455 machine_pwd,
02456 sec_chan_type,
02457 pneg_flags);
02458
02459 if (!NT_STATUS_IS_OK(*perr)) {
02460 DEBUG(3,("get_schannel_session_key_common: rpccli_netlogon_setup_creds "
02461 "failed with result %s to server %s, domain %s, machine account %s.\n",
02462 nt_errstr(*perr), cli->desthost, domain, machine_account ));
02463 return False;
02464 }
02465
02466 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
02467 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
02468 cli->desthost));
02469 *perr = NT_STATUS_INVALID_NETWORK_RESPONSE;
02470 return False;
02471 }
02472
02473 return True;
02474 }
02475
02476
02477
02478
02479
02480
02481
02482 struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli,
02483 const char *domain,
02484 uint32 *pneg_flags,
02485 NTSTATUS *perr)
02486 {
02487 struct rpc_pipe_client *netlogon_pipe = NULL;
02488
02489 netlogon_pipe = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, perr);
02490 if (!netlogon_pipe) {
02491 return NULL;
02492 }
02493
02494 if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
02495 pneg_flags, perr))
02496 {
02497 cli_rpc_pipe_close(netlogon_pipe);
02498 return NULL;
02499 }
02500
02501 return netlogon_pipe;
02502 }
02503
02504
02505
02506
02507
02508
02509
02510 struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
02511 int pipe_idx,
02512 enum pipe_auth_level auth_level,
02513 const char *domain,
02514 const struct dcinfo *pdc,
02515 NTSTATUS *perr)
02516 {
02517 struct rpc_pipe_client *result;
02518
02519 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
02520 if (result == NULL) {
02521 return NULL;
02522 }
02523
02524 result->auth.a_u.schannel_auth = TALLOC_ZERO_P(result->mem_ctx, struct schannel_auth_struct);
02525 if (!result->auth.a_u.schannel_auth) {
02526 cli_rpc_pipe_close(result);
02527 *perr = NT_STATUS_NO_MEMORY;
02528 return NULL;
02529 }
02530
02531 result->domain = domain;
02532 memcpy(result->auth.a_u.schannel_auth->sess_key, pdc->sess_key, 16);
02533
02534 *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_SCHANNEL, auth_level);
02535 if (!NT_STATUS_IS_OK(*perr)) {
02536 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: cli_rpc_pipe_bind failed with error %s\n",
02537 nt_errstr(*perr) ));
02538 cli_rpc_pipe_close(result);
02539 return NULL;
02540 }
02541
02542
02543 if (result->dc) {
02544 *result->dc = *pdc;
02545 }
02546
02547 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
02548 "for domain %s "
02549 "and bound using schannel.\n",
02550 result->pipe_name, cli->desthost, domain ));
02551
02552 return result;
02553 }
02554
02555
02556
02557
02558
02559
02560
02561 static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
02562 const char *domain,
02563 const char *username,
02564 const char *password,
02565 uint32 *pneg_flags,
02566 NTSTATUS *perr)
02567 {
02568 struct rpc_pipe_client *netlogon_pipe = NULL;
02569
02570 netlogon_pipe = cli_rpc_pipe_open_spnego_ntlmssp(cli, PI_NETLOGON, PIPE_AUTH_LEVEL_PRIVACY, domain, username, password, perr);
02571 if (!netlogon_pipe) {
02572 return NULL;
02573 }
02574
02575 if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
02576 pneg_flags, perr))
02577 {
02578 cli_rpc_pipe_close(netlogon_pipe);
02579 return NULL;
02580 }
02581
02582 return netlogon_pipe;
02583 }
02584
02585
02586
02587
02588
02589
02590
02591 struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
02592 int pipe_idx,
02593 enum pipe_auth_level auth_level,
02594 const char *domain,
02595 const char *username,
02596 const char *password,
02597 NTSTATUS *perr)
02598 {
02599 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
02600 struct rpc_pipe_client *netlogon_pipe = NULL;
02601 struct rpc_pipe_client *result = NULL;
02602
02603 netlogon_pipe = get_schannel_session_key_auth_ntlmssp(cli, domain, username,
02604 password, &neg_flags, perr);
02605 if (!netlogon_pipe) {
02606 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
02607 "key from server %s for domain %s.\n",
02608 cli->desthost, domain ));
02609 return NULL;
02610 }
02611
02612 result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
02613 auth_level,
02614 domain, netlogon_pipe->dc, perr);
02615
02616
02617 cli_rpc_pipe_close(netlogon_pipe);
02618
02619 return result;
02620 }
02621
02622
02623
02624
02625
02626
02627 struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli,
02628 int pipe_idx,
02629 enum pipe_auth_level auth_level,
02630 const char *domain,
02631 NTSTATUS *perr)
02632 {
02633 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
02634 struct rpc_pipe_client *netlogon_pipe = NULL;
02635 struct rpc_pipe_client *result = NULL;
02636
02637 netlogon_pipe = get_schannel_session_key(cli, domain, &neg_flags, perr);
02638 if (!netlogon_pipe) {
02639 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
02640 "key from server %s for domain %s.\n",
02641 cli->desthost, domain ));
02642 return NULL;
02643 }
02644
02645 result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
02646 auth_level,
02647 domain, netlogon_pipe->dc, perr);
02648
02649
02650 cli_rpc_pipe_close(netlogon_pipe);
02651
02652 return result;
02653 }
02654
02655 #ifdef HAVE_KRB5
02656
02657
02658
02659
02660
02661 static void kerberos_auth_struct_free(struct cli_pipe_auth_data *a)
02662 {
02663 data_blob_free(&a->a_u.kerberos_auth->session_key);
02664 }
02665
02666 #endif
02667
02668
02669
02670
02671
02672
02673
02674 struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli,
02675 int pipe_idx,
02676 enum pipe_auth_level auth_level,
02677 const char *service_princ,
02678 const char *username,
02679 const char *password,
02680 NTSTATUS *perr)
02681 {
02682 #ifdef HAVE_KRB5
02683 struct rpc_pipe_client *result;
02684
02685 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
02686 if (result == NULL) {
02687 return NULL;
02688 }
02689
02690
02691 if (!service_princ) {
02692 service_princ = talloc_asprintf(result->mem_ctx, "%s$@%s",
02693 cli->desthost, lp_realm() );
02694 if (!service_princ) {
02695 cli_rpc_pipe_close(result);
02696 return NULL;
02697 }
02698 }
02699
02700
02701 if (username && password) {
02702 int ret = kerberos_kinit_password(username, password, 0, NULL);
02703 if (ret) {
02704 cli_rpc_pipe_close(result);
02705 return NULL;
02706 }
02707 }
02708
02709 result->auth.a_u.kerberos_auth = TALLOC_ZERO_P(cli->mem_ctx, struct kerberos_auth_struct);
02710 if (!result->auth.a_u.kerberos_auth) {
02711 cli_rpc_pipe_close(result);
02712 *perr = NT_STATUS_NO_MEMORY;
02713 return NULL;
02714 }
02715
02716 result->auth.a_u.kerberos_auth->service_principal = service_princ;
02717 result->auth.cli_auth_data_free_func = kerberos_auth_struct_free;
02718
02719 *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_KRB5, auth_level);
02720 if (!NT_STATUS_IS_OK(*perr)) {
02721 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed with error %s\n",
02722 nt_errstr(*perr) ));
02723 cli_rpc_pipe_close(result);
02724 return NULL;
02725 }
02726
02727 return result;
02728 #else
02729 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
02730 return NULL;
02731 #endif
02732 }
02733
02734 #if 0
02735
02736
02737
02738
02739
02740 void cli_rpc_pipe_close(struct rpc_pipe_client *cli)
02741 {
02742 if (!cli_close(cli->cli, cli->fnum)) {
02743 DEBUG(0,("cli_rpc_pipe_close: cli_close failed on pipe %s "
02744 "to machine %s. Error was %s\n",
02745 cli->pipe_name),
02746 cli->cli->desthost,
02747 cli_errstr(cli->cli)));
02748 }
02749
02750 if (cli->auth.cli_auth_data_free_func) {
02751 (*cli->auth.cli_auth_data_free_func)(&cli->auth);
02752 }
02753 DEBUG(10,("cli_rpc_pipe_close: closed pipe %s to machine %s\n",
02754 cli->pipe_name, cli->cli->desthost ));
02755
02756 DLIST_REMOVE(cli->cli->pipe_list, cli);
02757 talloc_destroy(cli->mem_ctx);
02758 }
02759 #endif