Changeset 920 for trunk/server/source3/rpc_client
- Timestamp:
- Jun 9, 2016, 2:23:12 PM (10 years ago)
- Location:
- trunk/server
- Files:
-
- 3 edited
-
. (modified) (1 prop)
-
source3/rpc_client/cli_pipe.c (modified) (40 diffs)
-
source3/rpc_client/rpc_client.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 919
- Property svn:mergeinfo changed
-
trunk/server/source3/rpc_client/cli_pipe.c
r862 r920 29 29 #include "ntlmssp_wrap.h" 30 30 #include "librpc/gen_ndr/ndr_dcerpc.h" 31 31 32 #include "librpc/rpc/dcerpc.h" 32 33 #include "librpc/crypto/gse.h" … … 400 401 DATA_BLOB *pdu, 401 402 uint8_t expected_pkt_type, 403 402 404 DATA_BLOB *rdata, 403 405 DATA_BLOB *reply_pdu) 404 406 { 405 struct dcerpc_response *r; 407 const struct dcerpc_response *r = NULL; 408 DATA_BLOB tmp_stub = data_blob_null; 406 409 NTSTATUS ret = NT_STATUS_OK; 407 size_t pad_len = 0;408 410 409 411 /* … … 413 415 *rdata = *pdu; 414 416 417 418 419 420 421 422 423 424 425 426 427 428 429 415 430 /* Ensure we have the correct type. */ 416 431 switch (pkt->ptype) { 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 417 475 case DCERPC_PKT_ALTER_RESP: 418 case DCERPC_PKT_BIND_ACK: 419 420 /* Client code never receives this kind of packets */ 476 ret = dcerpc_verify_ncacn_packet_header(pkt, 477 expected_pkt_type, 478 pkt->u.alter_resp.auth_info.length, 479 DCERPC_PFC_FLAG_FIRST | 480 DCERPC_PFC_FLAG_LAST, 481 DCERPC_PFC_FLAG_CONC_MPX | 482 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN); 483 if (!NT_STATUS_IS_OK(ret)) { 484 DEBUG(1, (__location__ ": Connection to %s got an unexpected " 485 "RPC packet type - %u, expected %u: %s\n", 486 rpccli_pipe_txt(talloc_tos(), cli), 487 pkt->ptype, expected_pkt_type, 488 nt_errstr(ret))); 489 NDR_PRINT_DEBUG(ncacn_packet, pkt); 490 return ret; 491 } 492 421 493 break; 422 494 423 424 495 case DCERPC_PKT_RESPONSE: 425 496 426 497 r = &pkt->u.response; 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 427 517 428 518 /* Here's where we deal with incoming sign/seal. */ 429 519 ret = dcerpc_check_auth(cli->auth, pkt, 430 & r->stub_and_verifier,520 &, 431 521 DCERPC_RESPONSE_LENGTH, 432 pdu , &pad_len);522 pdu); 433 523 if (!NT_STATUS_IS_OK(ret)) { 524 525 526 527 528 529 434 530 return ret; 435 531 } 436 532 437 if (pkt->frag_length < DCERPC_RESPONSE_LENGTH + pad_len) {438 return NT_STATUS_BUFFER_TOO_SMALL;439 }440 441 533 /* Point the return values at the NDR data. */ 442 rdata->data = r->stub_and_verifier.data; 443 444 if (pkt->auth_length) { 445 /* We've already done integer wrap tests in 446 * dcerpc_check_auth(). */ 447 rdata->length = r->stub_and_verifier.length 448 - pad_len 449 - DCERPC_AUTH_TRAILER_LENGTH 450 - pkt->auth_length; 451 } else { 452 rdata->length = r->stub_and_verifier.length; 453 } 454 455 DEBUG(10, ("Got pdu len %lu, data_len %lu, ss_len %u\n", 534 *rdata = tmp_stub; 535 536 DEBUG(10, ("Got pdu len %lu, data_len %lu\n", 456 537 (long unsigned int)pdu->length, 457 (long unsigned int)rdata->length, 458 (unsigned int)pad_len)); 538 (long unsigned int)rdata->length)); 459 539 460 540 /* … … 477 557 break; 478 558 479 case DCERPC_PKT_BIND_NAK:480 DEBUG(1, (__location__ ": Bind NACK received from %s!\n",481 rpccli_pipe_txt(talloc_tos(), cli)));482 /* Use this for now... */483 return NT_STATUS_NETWORK_ACCESS_DENIED;484 485 559 case DCERPC_PKT_FAULT: 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 486 576 487 577 DEBUG(1, (__location__ ": RPC fault code %s received " … … 498 588 (unsigned int)pkt->ptype, 499 589 rpccli_pipe_txt(talloc_tos(), cli))); 500 return NT_STATUS_INVALID_INFO_CLASS; 501 } 502 503 if (pkt->ptype != expected_pkt_type) { 590 return NT_STATUS_RPC_PROTOCOL_ERROR; 591 } 592 593 594 if (pkt->call_id != call_id) { 504 595 DEBUG(3, (__location__ ": Connection to %s got an unexpected " 505 "RPC packet type- %u, not %u\n",596 "RPC - %u, not %u\n", 506 597 rpccli_pipe_txt(talloc_tos(), cli), 507 pkt->ptype, expected_pkt_type)); 508 return NT_STATUS_INVALID_INFO_CLASS; 509 } 510 511 /* Do this just before return - we don't want to modify any rpc header 512 data before now as we may have needed to do cryptographic actions on 513 it before. */ 514 515 if ((pkt->ptype == DCERPC_PKT_BIND_ACK) && 516 !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) { 517 DEBUG(5, (__location__ ": bug in server (AS/U?), setting " 518 "fragment first/last ON.\n")); 519 pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; 598 pkt->call_id, call_id)); 599 return NT_STATUS_RPC_PROTOCOL_ERROR; 520 600 } 521 601 … … 874 954 state->pkt = talloc(state, struct ncacn_packet); 875 955 if (!state->pkt) { 956 957 958 959 960 961 876 962 tevent_req_nterror(req, NT_STATUS_NO_MEMORY); 877 963 return; … … 883 969 !state->endianess); 884 970 if (!NT_STATUS_IS_OK(status)) { 971 972 973 974 975 976 885 977 tevent_req_nterror(req, status); 886 return;887 }888 889 if (state->incoming_frag.length != state->pkt->frag_length) {890 DEBUG(5, ("Incorrect pdu length %u, expected %u\n",891 (unsigned int)state->incoming_frag.length,892 (unsigned int)state->pkt->frag_length));893 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);894 978 return; 895 979 } … … 899 983 &state->incoming_frag, 900 984 state->expected_pkt_type, 985 901 986 &rdata, 902 987 &state->reply_pdu); … … 907 992 nt_errstr(status))); 908 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 909 1016 if (!NT_STATUS_IS_OK(status)) { 910 1017 tevent_req_nterror(req, status); … … 931 1038 state->endianess?"little":"big", 932 1039 state->pkt->drep[0]?"little":"big")); 933 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); 1040 /* 1041 * TODO: do a real async disconnect ... 1042 * 1043 * For now do it sync... 1044 */ 1045 TALLOC_FREE(state->cli->transport); 1046 tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR); 1047 return; 1048 } 1049 1050 if (state->reply_pdu_offset + rdata.length > MAX_RPC_DATA_SIZE) { 1051 /* 1052 * TODO: do a real async disconnect ... 1053 * 1054 * For now do it sync... 1055 */ 1056 TALLOC_FREE(state->cli->transport); 1057 tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR); 934 1058 return; 935 1059 } … … 939 1063 if (!data_blob_realloc(NULL, &state->reply_pdu, 940 1064 state->reply_pdu_offset + rdata.length)) { 1065 1066 1067 1068 1069 1070 941 1071 tevent_req_nterror(req, NT_STATUS_NO_MEMORY); 942 1072 return; … … 968 1098 state->call_id, 969 1099 &state->incoming_frag); 1100 1101 1102 1103 1104 1105 1106 1107 970 1108 if (tevent_req_nomem(subreq, req)) { 971 1109 return; … … 1237 1375 auth->auth_level, 1238 1376 0, /* auth_pad_length */ 1239 1, /* auth_context_id */1377 1240 1378 &auth_token, 1241 1379 &auth_info); … … 1270 1408 DATA_BLOB *req_data; 1271 1409 uint32_t req_data_sent; 1410 1411 1412 1413 1272 1414 DATA_BLOB rpc_out; 1273 1415 DATA_BLOB reply_pdu; … … 1276 1418 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq); 1277 1419 static void rpc_api_pipe_req_done(struct tevent_req *subreq); 1420 1278 1421 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state, 1279 1422 bool *is_last_frag); … … 1311 1454 } 1312 1455 1456 1457 1458 1459 1460 1313 1461 status = prepare_next_frag(state, &is_last_frag); 1314 1462 if (!NT_STATUS_IS_OK(status)) { … … 1345 1493 } 1346 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1347 1618 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state, 1348 1619 bool *is_last_frag) 1349 1620 { 1350 size_t data_sent_thistime;1351 1621 size_t auth_len; 1352 1622 size_t frag_len; … … 1354 1624 size_t pad_len; 1355 1625 size_t data_left; 1356 NTSTATUS status; 1626 size_t data_thistime; 1627 size_t trailer_left; 1628 size_t trailer_thistime = 0; 1629 size_t total_left; 1630 size_t total_thistime; 1631 NTSTATUS status; 1632 bool ok; 1357 1633 union dcerpc_payload u; 1358 1634 1359 1635 data_left = state->req_data->length - state->req_data_sent; 1636 1637 1638 1639 1640 1641 1642 1643 1360 1644 1361 1645 status = dcerpc_guess_sizes(state->cli->auth, 1362 DCERPC_REQUEST_LENGTH, data_left,1646 DCERPC_REQUEST_LENGTH, _left, 1363 1647 state->cli->max_xmit_frag, 1364 1648 CLIENT_NDR_PADDING_SIZE, 1365 & data_sent_thistime,1649 &_thistime, 1366 1650 &frag_len, &auth_len, &pad_len); 1367 1651 if (!NT_STATUS_IS_OK(status)) { … … 1373 1657 } 1374 1658 1375 if ( data_sent_thistime == data_left) {1659 if (_left) { 1376 1660 flags |= DCERPC_PFC_FLAG_LAST; 1377 1661 } 1378 1662 1663 1664 1665 1666 1667 1379 1668 data_blob_free(&state->rpc_out); 1380 1669 1381 1670 ZERO_STRUCT(u.request); 1382 1671 1383 u.request.alloc_hint = state->req_data->length;1672 u.request.alloc_hint = ; 1384 1673 u.request.context_id = 0; 1385 1674 u.request.opnum = state->op_num; … … 1401 1690 dcerpc_set_frag_length(&state->rpc_out, frag_len); 1402 1691 1403 /* Copy in the data. */ 1404 if (!data_blob_append(NULL, &state->rpc_out, 1692 if (data_thistime > 0) { 1693 /* Copy in the data. */ 1694 ok = data_blob_append(NULL, &state->rpc_out, 1405 1695 state->req_data->data + state->req_data_sent, 1406 data_sent_thistime)) { 1407 return NT_STATUS_NO_MEMORY; 1696 data_thistime); 1697 if (!ok) { 1698 return NT_STATUS_NO_MEMORY; 1699 } 1700 state->req_data_sent += data_thistime; 1701 } 1702 1703 if (trailer_thistime > 0) { 1704 /* Copy in the verification trailer. */ 1705 ok = data_blob_append(NULL, &state->rpc_out, 1706 state->req_trailer.data + state->req_trailer_sent, 1707 trailer_thistime); 1708 if (!ok) { 1709 return NT_STATUS_NO_MEMORY; 1710 } 1711 state->req_trailer_sent += trailer_thistime; 1408 1712 } 1409 1713 … … 1425 1729 } 1426 1730 1427 state->req_data_sent += data_sent_thistime;1428 1731 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0); 1429 1732 … … 1489 1792 return; 1490 1793 } 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1491 1808 tevent_req_done(req); 1492 1809 } … … 1560 1877 static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx, 1561 1878 struct rpc_pipe_client *cli, 1562 uint32 rpc_call_id, 1563 enum dcerpc_AuthType auth_type, 1564 enum dcerpc_AuthLevel auth_level, 1879 struct pipe_auth_data *auth, 1880 uint32_t rpc_call_id, 1565 1881 DATA_BLOB *pauth_blob, 1566 1882 DATA_BLOB *rpc_out) … … 1572 1888 1573 1889 status = dcerpc_push_dcerpc_auth(mem_ctx, 1574 auth _type,1575 auth _level,1890 auth_type, 1891 auth_level, 1576 1892 0, /* auth_pad_length */ 1577 1, /* auth_context_id */1893 1578 1894 pauth_blob, 1579 1895 &u.auth3.auth_info); … … 1605 1921 1606 1922 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx, 1607 enum dcerpc_AuthType auth_type, 1608 enum dcerpc_AuthLevel auth_level, 1609 uint32 rpc_call_id, 1923 struct pipe_auth_data *auth, 1924 uint32_t rpc_call_id, 1610 1925 const struct ndr_syntax_id *abstract, 1611 1926 const struct ndr_syntax_id *transfer, … … 1617 1932 1618 1933 status = dcerpc_push_dcerpc_auth(mem_ctx, 1619 auth _type,1620 auth _level,1934 auth_type, 1935 auth_level, 1621 1936 0, /* auth_pad_length */ 1622 1, /* auth_context_id */1937 1623 1938 pauth_blob, 1624 1939 &auth_info); … … 1648 1963 bool auth3; 1649 1964 uint32_t rpc_call_id; 1965 1966 1967 1968 1969 1650 1970 }; 1651 1971 1652 1972 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq); 1973 1653 1974 static NTSTATUS rpc_bind_next_send(struct tevent_req *req, 1654 1975 struct rpc_pipe_bind_state *state, … … 1754 2075 case DCERPC_AUTH_TYPE_NONE: 1755 2076 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM: 1756 case DCERPC_AUTH_TYPE_SCHANNEL:1757 2077 /* Bind complete. */ 1758 2078 tevent_req_done(req); 1759 2079 return; 1760 2080 1761 case DCERPC_AUTH_TYPE_NTLMSSP: 1762 case DCERPC_AUTH_TYPE_SPNEGO: 1763 case DCERPC_AUTH_TYPE_KRB5: 1764 /* Paranoid lenght checks */ 1765 if (pkt->frag_length < DCERPC_AUTH_TRAILER_LENGTH 1766 + pkt->auth_length) { 1767 tevent_req_nterror(req, 1768 NT_STATUS_INFO_LENGTH_MISMATCH); 2081 case DCERPC_AUTH_TYPE_SCHANNEL: 2082 rpc_pipe_bind_step_two_trigger(req); 2083 return; 2084 2085 default: 2086 if (pkt->auth_length == 0) { 2087 tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR); 1769 2088 return; 1770 2089 } 1771 2090 /* get auth credentials */ 1772 status = dcerpc_pull_ dcerpc_auth(talloc_tos(),1773 &pkt->u.bind_ack.auth_info,1774 &auth, false);2091 status = dcerpc_pull_talloc_tos(), 2092 &pkt->u.bind_ack.auth_info, 2093 e); 1775 2094 if (!NT_STATUS_IS_OK(status)) { 1776 2095 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n", … … 1779 2098 return; 1780 2099 } 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 1781 2123 break; 1782 1783 default:1784 goto err_out;1785 2124 } 1786 2125 … … 1870 2209 } 1871 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 1872 2358 static NTSTATUS rpc_bind_next_send(struct tevent_req *req, 1873 2359 struct rpc_pipe_bind_state *state, … … 1881 2367 data_blob_free(&state->rpc_out); 1882 2368 1883 status = create_rpc_alter_context(state, 1884 auth->auth_type, 1885 auth->auth_level, 2369 status = create_rpc_alter_context(state, auth, 1886 2370 state->rpc_call_id, 1887 2371 &state->cli->abstract_syntax, … … 1916 2400 data_blob_free(&state->rpc_out); 1917 2401 1918 status = create_rpc_bind_auth3(state, state->cli, 2402 status = create_rpc_bind_auth3(state, state->cli, 1919 2403 state->rpc_call_id, 1920 auth->auth_type,1921 auth->auth_level,1922 2404 auth_token, 1923 2405 &state->rpc_out); … … 2153 2635 * TODO: do a real async disconnect ... 2154 2636 * 2155 * For now the caller needs to free rpc_cli2637 * For now 2156 2638 */ 2639 2157 2640 hs->rpc_cli = NULL; 2158 2641 … … 2291 2774 result->auth_type = DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM; 2292 2775 result->auth_level = DCERPC_AUTH_LEVEL_CONNECT; 2776 2293 2777 2294 2778 result->user_name = talloc_strdup(result, ""); … … 2315 2799 result->auth_type = DCERPC_AUTH_TYPE_NONE; 2316 2800 result->auth_level = DCERPC_AUTH_LEVEL_NONE; 2801 2317 2802 2318 2803 result->user_name = talloc_strdup(result, ""); … … 2352 2837 result->auth_type = auth_type; 2353 2838 result->auth_level = auth_level; 2839 2354 2840 2355 2841 result->user_name = talloc_strdup(result, username); … … 2423 2909 result->auth_type = DCERPC_AUTH_TYPE_SCHANNEL; 2424 2910 result->auth_level = auth_level; 2911 2425 2912 2426 2913 result->user_name = talloc_strdup(result, ""); … … 3087 3574 auth->auth_type = DCERPC_AUTH_TYPE_KRB5; 3088 3575 auth->auth_level = auth_level; 3576 3089 3577 3090 3578 if (!username) { … … 3157 3645 auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO; 3158 3646 auth->auth_level = auth_level; 3647 3159 3648 3160 3649 if (!username) { … … 3231 3720 auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO; 3232 3721 auth->auth_level = auth_level; 3722 3233 3723 3234 3724 if (!username) { -
trunk/server/source3/rpc_client/rpc_client.h
r918 r920 40 40 struct ndr_syntax_id abstract_syntax; 41 41 struct ndr_syntax_id transfer_syntax; 42 42 43 43 44 char *desthost;
Note:
See TracChangeset
for help on using the changeset viewer.
