Ignore:
Timestamp:
Jun 9, 2016, 2:23:12 PM (10 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: apply latest security patches to trunk

Location:
trunk/server
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source3/rpc_client/cli_pipe.c

    r862 r920  
    2929#include "ntlmssp_wrap.h"
    3030#include "librpc/gen_ndr/ndr_dcerpc.h"
     31
    3132#include "librpc/rpc/dcerpc.h"
    3233#include "librpc/crypto/gse.h"
     
    400401                                                DATA_BLOB *pdu,
    401402                                                uint8_t expected_pkt_type,
     403
    402404                                                DATA_BLOB *rdata,
    403405                                                DATA_BLOB *reply_pdu)
    404406{
    405         struct dcerpc_response *r;
     407        const struct dcerpc_response *r = NULL;
     408        DATA_BLOB tmp_stub = data_blob_null;
    406409        NTSTATUS ret = NT_STATUS_OK;
    407         size_t pad_len = 0;
    408410
    409411        /*
     
    413415        *rdata = *pdu;
    414416
     417
     418
     419
     420
     421
     422
     423
     424
     425
     426
     427
     428
     429
    415430        /* Ensure we have the correct type. */
    416431        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
    417475        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
    421493                break;
    422494
    423 
    424495        case DCERPC_PKT_RESPONSE:
    425496
    426497                r = &pkt->u.response;
     498
     499
     500
     501
     502
     503
     504
     505
     506
     507
     508
     509
     510
     511
     512
     513
     514
     515
     516
    427517
    428518                /* Here's where we deal with incoming sign/seal. */
    429519                ret = dcerpc_check_auth(cli->auth, pkt,
    430                                         &r->stub_and_verifier,
     520                                        &,
    431521                                        DCERPC_RESPONSE_LENGTH,
    432                                         pdu, &pad_len);
     522                                        pdu);
    433523                if (!NT_STATUS_IS_OK(ret)) {
     524
     525
     526
     527
     528
     529
    434530                        return ret;
    435531                }
    436532
    437                 if (pkt->frag_length < DCERPC_RESPONSE_LENGTH + pad_len) {
    438                         return NT_STATUS_BUFFER_TOO_SMALL;
    439                 }
    440 
    441533                /* 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",
    456537                           (long unsigned int)pdu->length,
    457                            (long unsigned int)rdata->length,
    458                            (unsigned int)pad_len));
     538                           (long unsigned int)rdata->length));
    459539
    460540                /*
     
    477557                break;
    478558
    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 
    485559        case DCERPC_PKT_FAULT:
     560
     561
     562
     563
     564
     565
     566
     567
     568
     569
     570
     571
     572
     573
     574
     575
    486576
    487577                DEBUG(1, (__location__ ": RPC fault code %s received "
     
    498588                          (unsigned int)pkt->ptype,
    499589                          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) {
    504595                DEBUG(3, (__location__ ": Connection to %s got an unexpected "
    505                           "RPC packet type - %u, not %u\n",
     596                          "RPC - %u, not %u\n",
    506597                          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;
    520600        }
    521601
     
    874954        state->pkt = talloc(state, struct ncacn_packet);
    875955        if (!state->pkt) {
     956
     957
     958
     959
     960
     961
    876962                tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
    877963                return;
     
    883969                                          !state->endianess);
    884970        if (!NT_STATUS_IS_OK(status)) {
     971
     972
     973
     974
     975
     976
    885977                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);
    894978                return;
    895979        }
     
    899983                                                &state->incoming_frag,
    900984                                                state->expected_pkt_type,
     985
    901986                                                &rdata,
    902987                                                &state->reply_pdu);
     
    907992                  nt_errstr(status)));
    908993
     994
     995
     996
     997
     998
     999
     1000
     1001
     1002
     1003
     1004
     1005
     1006
     1007
     1008
     1009
     1010
     1011
     1012
     1013
     1014
     1015
    9091016        if (!NT_STATUS_IS_OK(status)) {
    9101017                tevent_req_nterror(req, status);
     
    9311038                         state->endianess?"little":"big",
    9321039                         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);
    9341058                return;
    9351059        }
     
    9391063                if (!data_blob_realloc(NULL, &state->reply_pdu,
    9401064                                state->reply_pdu_offset + rdata.length)) {
     1065
     1066
     1067
     1068
     1069
     1070
    9411071                        tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
    9421072                        return;
     
    9681098                                        state->call_id,
    9691099                                        &state->incoming_frag);
     1100
     1101
     1102
     1103
     1104
     1105
     1106
     1107
    9701108        if (tevent_req_nomem(subreq, req)) {
    9711109                return;
     
    12371375                                                auth->auth_level,
    12381376                                                0, /* auth_pad_length */
    1239                                                 1, /* auth_context_id */
     1377                                               
    12401378                                                &auth_token,
    12411379                                                &auth_info);
     
    12701408        DATA_BLOB *req_data;
    12711409        uint32_t req_data_sent;
     1410
     1411
     1412
     1413
    12721414        DATA_BLOB rpc_out;
    12731415        DATA_BLOB reply_pdu;
     
    12761418static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
    12771419static void rpc_api_pipe_req_done(struct tevent_req *subreq);
     1420
    12781421static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
    12791422                                  bool *is_last_frag);
     
    13111454        }
    13121455
     1456
     1457
     1458
     1459
     1460
    13131461        status = prepare_next_frag(state, &is_last_frag);
    13141462        if (!NT_STATUS_IS_OK(status)) {
     
    13451493}
    13461494
     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
    13471618static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
    13481619                                  bool *is_last_frag)
    13491620{
    1350         size_t data_sent_thistime;
    13511621        size_t auth_len;
    13521622        size_t frag_len;
     
    13541624        size_t pad_len;
    13551625        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;
    13571633        union dcerpc_payload u;
    13581634
    13591635        data_left = state->req_data->length - state->req_data_sent;
     1636
     1637
     1638
     1639
     1640
     1641
     1642
     1643
    13601644
    13611645        status = dcerpc_guess_sizes(state->cli->auth,
    1362                                     DCERPC_REQUEST_LENGTH, data_left,
     1646                                    DCERPC_REQUEST_LENGTH, _left,
    13631647                                    state->cli->max_xmit_frag,
    13641648                                    CLIENT_NDR_PADDING_SIZE,
    1365                                     &data_sent_thistime,
     1649                                    &_thistime,
    13661650                                    &frag_len, &auth_len, &pad_len);
    13671651        if (!NT_STATUS_IS_OK(status)) {
     
    13731657        }
    13741658
    1375         if (data_sent_thistime == data_left) {
     1659        if (_left) {
    13761660                flags |= DCERPC_PFC_FLAG_LAST;
    13771661        }
    13781662
     1663
     1664
     1665
     1666
     1667
    13791668        data_blob_free(&state->rpc_out);
    13801669
    13811670        ZERO_STRUCT(u.request);
    13821671
    1383         u.request.alloc_hint    = state->req_data->length;
     1672        u.request.alloc_hint    = ;
    13841673        u.request.context_id    = 0;
    13851674        u.request.opnum         = state->op_num;
     
    14011690        dcerpc_set_frag_length(&state->rpc_out, frag_len);
    14021691
    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,
    14051695                                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;
    14081712        }
    14091713
     
    14251729        }
    14261730
    1427         state->req_data_sent += data_sent_thistime;
    14281731        *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
    14291732
     
    14891792                return;
    14901793        }
     1794
     1795
     1796
     1797
     1798
     1799
     1800
     1801
     1802
     1803
     1804
     1805
     1806
     1807
    14911808        tevent_req_done(req);
    14921809}
     
    15601877static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
    15611878                                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,
    15651881                                DATA_BLOB *pauth_blob,
    15661882                                DATA_BLOB *rpc_out)
     
    15721888
    15731889        status = dcerpc_push_dcerpc_auth(mem_ctx,
    1574                                          auth_type,
    1575                                          auth_level,
     1890                                         auth_type,
     1891                                         auth_level,
    15761892                                         0, /* auth_pad_length */
    1577                                          1, /* auth_context_id */
     1893                                         
    15781894                                         pauth_blob,
    15791895                                         &u.auth3.auth_info);
     
    16051921
    16061922static 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,
    16101925                                        const struct ndr_syntax_id *abstract,
    16111926                                        const struct ndr_syntax_id *transfer,
     
    16171932
    16181933        status = dcerpc_push_dcerpc_auth(mem_ctx,
    1619                                          auth_type,
    1620                                          auth_level,
     1934                                         auth_type,
     1935                                         auth_level,
    16211936                                         0, /* auth_pad_length */
    1622                                          1, /* auth_context_id */
     1937                                         
    16231938                                         pauth_blob,
    16241939                                         &auth_info);
     
    16481963        bool auth3;
    16491964        uint32_t rpc_call_id;
     1965
     1966
     1967
     1968
     1969
    16501970};
    16511971
    16521972static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
     1973
    16531974static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
    16541975                                   struct rpc_pipe_bind_state *state,
     
    17542075        case DCERPC_AUTH_TYPE_NONE:
    17552076        case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
    1756         case DCERPC_AUTH_TYPE_SCHANNEL:
    17572077                /* Bind complete. */
    17582078                tevent_req_done(req);
    17592079                return;
    17602080
    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);
    17692088                        return;
    17702089                }
    17712090                /* 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);
    17752094                if (!NT_STATUS_IS_OK(status)) {
    17762095                        DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
     
    17792098                        return;
    17802099                }
     2100
     2101
     2102
     2103
     2104
     2105
     2106
     2107
     2108
     2109
     2110
     2111
     2112
     2113
     2114
     2115
     2116
     2117
     2118
     2119
     2120
     2121
     2122
    17812123                break;
    1782 
    1783         default:
    1784                 goto err_out;
    17852124        }
    17862125
     
    18702209}
    18712210
     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
    18722358static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
    18732359                                   struct rpc_pipe_bind_state *state,
     
    18812367        data_blob_free(&state->rpc_out);
    18822368
    1883         status = create_rpc_alter_context(state,
    1884                                           auth->auth_type,
    1885                                           auth->auth_level,
     2369        status = create_rpc_alter_context(state, auth,
    18862370                                          state->rpc_call_id,
    18872371                                          &state->cli->abstract_syntax,
     
    19162400        data_blob_free(&state->rpc_out);
    19172401
    1918         status = create_rpc_bind_auth3(state, state->cli,
     2402        status = create_rpc_bind_auth3(state, state->cli,
    19192403                                        state->rpc_call_id,
    1920                                         auth->auth_type,
    1921                                         auth->auth_level,
    19222404                                        auth_token,
    19232405                                        &state->rpc_out);
     
    21532635         * TODO: do a real async disconnect ...
    21542636         *
    2155          * For now the caller needs to free rpc_cli
     2637         * For now
    21562638         */
     2639
    21572640        hs->rpc_cli = NULL;
    21582641
     
    22912774        result->auth_type = DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM;
    22922775        result->auth_level = DCERPC_AUTH_LEVEL_CONNECT;
     2776
    22932777
    22942778        result->user_name = talloc_strdup(result, "");
     
    23152799        result->auth_type = DCERPC_AUTH_TYPE_NONE;
    23162800        result->auth_level = DCERPC_AUTH_LEVEL_NONE;
     2801
    23172802
    23182803        result->user_name = talloc_strdup(result, "");
     
    23522837        result->auth_type = auth_type;
    23532838        result->auth_level = auth_level;
     2839
    23542840
    23552841        result->user_name = talloc_strdup(result, username);
     
    24232909        result->auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
    24242910        result->auth_level = auth_level;
     2911
    24252912
    24262913        result->user_name = talloc_strdup(result, "");
     
    30873574        auth->auth_type = DCERPC_AUTH_TYPE_KRB5;
    30883575        auth->auth_level = auth_level;
     3576
    30893577
    30903578        if (!username) {
     
    31573645        auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
    31583646        auth->auth_level = auth_level;
     3647
    31593648
    31603649        if (!username) {
     
    32313720        auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
    32323721        auth->auth_level = auth_level;
     3722
    32333723
    32343724        if (!username) {
  • trunk/server/source3/rpc_client/rpc_client.h

    r918 r920  
    4040        struct ndr_syntax_id abstract_syntax;
    4141        struct ndr_syntax_id transfer_syntax;
     42
    4243
    4344        char *desthost;
Note: See TracChangeset for help on using the changeset viewer.