Changeset 920 for trunk/server/librpc


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

Samba Server: apply latest security patches to trunk

Location:
trunk/server
Files:
12 edited
3 copied

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/librpc/idl/dcerpc.idl

    r862 r920  
    1010*/
    1111import "misc.idl";
     12
     13cpp_quote("extern const uint8_t DCERPC_SEC_VT_MAGIC[8];")
    1214
    1315interface dcerpc
     
    454456
    455457        /* pfc_flags values */
    456         const uint8 DCERPC_PFC_FLAG_FIRST               = 0x01; /* First fragment */
    457         const uint8 DCERPC_PFC_FLAG_LAST                = 0x02; /* Last fragment */
    458         const uint8 DCERPC_PFC_FLAG_PENDING_CANCEL      = 0x04; /* Cancel was pending at sender */
    459         const uint8 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN = DCERPC_PFC_FLAG_PENDING_CANCEL; /* depends on the pdu type */
    460         const uint8 DCERPC_PFC_FLAG_CONC_MPX            = 0x10; /* supports concurrent multiplexing of a single connection. */
    461         const uint8 DCERPC_PFC_FLAG_DID_NOT_EXECUTE     = 0x20; /* on a fault it means the server hasn't done anything */
    462         const uint8 DCERPC_PFC_FLAG_MAYBE               = 0x40; /* `maybe' call semantics requested */
    463         const uint8 DCERPC_PFC_FLAG_OBJECT_UUID         = 0x80; /* on valid guid is in the optional object field */
     458        typedef [bitmap8bit] bitmap {
     459                DCERPC_PFC_FLAG_FIRST           = 0x01, /* First fragment */
     460                DCERPC_PFC_FLAG_LAST            = 0x02, /* Last fragment */
     461                DCERPC_PFC_FLAG_PENDING_CANCEL_OR_HDR_SIGNING = 0x04, /* depends on the pdu type */
     462                DCERPC_PFC_FLAG_CONC_MPX        = 0x10, /* supports concurrent multiplexing of a single connection. */
     463                DCERPC_PFC_FLAG_DID_NOT_EXECUTE = 0x20, /* on a fault it means the server hasn't done anything */
     464                DCERPC_PFC_FLAG_MAYBE           = 0x40, /* `maybe' call semantics requested */
     465                DCERPC_PFC_FLAG_OBJECT_UUID     = 0x80 /* on valid guid is in the optional object field */
     466        } dcerpc_pfc_flags;
     467
     468        /* Cancel was pending at sender */
     469        const int DCERPC_PFC_FLAG_PENDING_CANCEL =
     470                DCERPC_PFC_FLAG_PENDING_CANCEL_OR_HDR_SIGNING;
     471        const ist DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN =
     472                DCERPC_PFC_FLAG_PENDING_CANCEL_OR_HDR_SIGNING;
    464473
    465474        /* these offsets are needed by the signing code */
     
    467476        const uint8 DCERPC_DREP_OFFSET     =  4;
    468477        const uint8 DCERPC_FRAG_LEN_OFFSET =  8;
     478        const uint32 DCERPC_FRAG_MAX_SIZE  = 5840;
    469479        const uint8 DCERPC_AUTH_LEN_OFFSET = 10;
    470480        const uint8 DCERPC_CALL_ID_OFFSET  = 12;
     481        const uint8 DCERPC_NCACN_PAYLOAD_OFFSET = 16;
     482        const uint32 DCERPC_NCACN_PAYLOAD_MAX_SIZE = 0x400000; /* 4 MByte */
    471483
    472484        /* little-endian flag */
     
    477489                uint8 rpc_vers_minor;   /* Minor version */
    478490                dcerpc_pkt_type ptype;  /* Packet type */
    479                 uint8 pfc_flags;        /* Fragmentation flags */
     491                dcerpc_pfc_flags pfc_flags; /* Fragmentation flags */
    480492                uint8 drep[4];          /* NDR data representation */
    481493                uint16 frag_length;     /* Total length of fragment */
     
    507519                [switch_is(ptype)] dcerpc_payload u;
    508520        } ncadg_packet;
     521
     522        typedef [bitmap16bit] bitmap {
     523                DCERPC_SEC_VT_COMMAND_ENUM  = 0x3FFF,
     524                DCERPC_SEC_VT_COMMAND_END   = 0x4000,
     525                DCERPC_SEC_VT_MUST_PROCESS  = 0x8000
     526        } dcerpc_sec_vt_command;
     527
     528        typedef [enum16bit] enum {
     529                DCERPC_SEC_VT_COMMAND_BITMASK1  = 0x0001,
     530                DCERPC_SEC_VT_COMMAND_PCONTEXT  = 0x0002,
     531                DCERPC_SEC_VT_COMMAND_HEADER2   = 0x0003
     532        } dcerpc_sec_vt_command_enum;
     533
     534        typedef [bitmap32bit] bitmap {
     535                DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING = 0x00000001
     536        } dcerpc_sec_vt_bitmask1;
     537
     538        typedef struct {
     539                ndr_syntax_id abstract_syntax;
     540                ndr_syntax_id transfer_syntax;
     541        } dcerpc_sec_vt_pcontext;
     542
     543        typedef struct {
     544                dcerpc_pkt_type ptype;  /* Packet type */
     545                [value(0)] uint8 reserved1;
     546                [value(0)] uint16 reserved2;
     547                uint8 drep[4];          /* NDR data representation */
     548                uint32 call_id;         /* Call identifier */
     549                uint16 context_id;
     550                uint16 opnum;
     551        } dcerpc_sec_vt_header2;
     552
     553        typedef [switch_type(dcerpc_sec_vt_command_enum),nodiscriminant] union {
     554        [case(DCERPC_SEC_VT_COMMAND_BITMASK1)] dcerpc_sec_vt_bitmask1 bitmask1;
     555        [case(DCERPC_SEC_VT_COMMAND_PCONTEXT)] dcerpc_sec_vt_pcontext pcontext;
     556        [case(DCERPC_SEC_VT_COMMAND_HEADER2)] dcerpc_sec_vt_header2 header2;
     557        [default,flag(NDR_REMAINING)] DATA_BLOB _unknown;
     558        } dcerpc_sec_vt_union;
     559
     560        typedef struct {
     561                dcerpc_sec_vt_command command;
     562                [switch_is(command & DCERPC_SEC_VT_COMMAND_ENUM)]
     563                        [subcontext(2),flag(NDR_SUBCONTEXT_NO_UNREAD_BYTES)]
     564                        dcerpc_sec_vt_union u;
     565        } dcerpc_sec_vt;
     566
     567        typedef [public,nopush,nopull] struct {
     568                uint16 count;
     569        } dcerpc_sec_vt_count;
     570
     571        /*
     572         * We assume that the whole verification trailer fits into
     573         * the last 1024 bytes after the stub data.
     574         *
     575         * There're currently only 3 commands defined and each should
     576         * only be used once.
     577         */
     578        const uint16 DCERPC_SEC_VT_MAX_SIZE = 1024;
     579
     580        typedef [public,flag(NDR_PAHEX)] struct {
     581                [flag(NDR_ALIGN4)] DATA_BLOB _pad;
     582                [value(DCERPC_SEC_VT_MAGIC)] uint8 magic[8];
     583                dcerpc_sec_vt_count count;
     584                dcerpc_sec_vt commands[count.count];
     585        } dcerpc_sec_verification_trailer;
    509586}
  • trunk/server/librpc/idl/idl_types.h

    r918 r920  
    4848#define NDR_RELATIVE_REVERSE LIBNDR_FLAG_RELATIVE_REVERSE
    4949#define NDR_NO_RELATIVE_REVERSE LIBNDR_FLAG_NO_RELATIVE_REVERSE
     50
     51#define NDR_SUBCONTEXT_NO_UNREAD_BYTES LIBNDR_FLAG_SUBCONTEXT_NO_UNREAD_BYTES
  • trunk/server/librpc/ndr/libndr.h

    r918 r920  
    125125#define LIBNDR_STRING_FLAGS             (0x7FFC)
    126126
     127/*
     128 * don't debug NDR_ERR_BUFSIZE failures,
     129 * as the available buffer might be incomplete.
     130 *
     131 * return NDR_ERR_INCOMPLETE_BUFFER instead.
     132 */
     133#define LIBNDR_FLAG_INCOMPLETE_BUFFER (1<<16)
     134
     135/*
     136 * This lets ndr_pull_subcontext_end() return
     137 * NDR_ERR_UNREAD_BYTES.
     138 */
     139#define LIBNDR_FLAG_SUBCONTEXT_NO_UNREAD_BYTES (1<<17)
     140
    127141/* set if relative pointers should *not* be marshalled in reverse order */
    128142#define LIBNDR_FLAG_NO_RELATIVE_REVERSE (1<<18)
     
    164178/* useful macro for debugging */
    165179#define NDR_PRINT_DEBUG(type, p) ndr_print_debug((ndr_print_fn_t)ndr_print_ ##type, #p, p)
     180#define NDR_PRINT_DEBUGC(dbgc_class, type, p) ndr_print_debugc(dbgc_class, (ndr_print_fn_t)ndr_print_ ##type, #p, p)
    166181#define NDR_PRINT_UNION_DEBUG(type, level, p) ndr_print_union_debug((ndr_print_fn_t)ndr_print_ ##type, #p, level, p)
    167182#define NDR_PRINT_FUNCTION_DEBUG(type, flags, p) ndr_print_function_debug((ndr_print_function_t)ndr_print_ ##type, #type, flags, p)
     
    200215        NDR_ERR_INVALID_POINTER,
    201216        NDR_ERR_UNREAD_BYTES,
    202         NDR_ERR_NDR64
     217        NDR_ERR_NDR64,
     218        NDR_ERR_FLAGS,
     219        NDR_ERR_INCOMPLETE_BUFFER
    203220};
    204221
     
    218235/*
    219236  flags passed to control parse flow
     237  These are deliberately in a different range to the NDR_IN/NDR_OUT
     238  flags to catch mixups
    220239*/
    221 #define NDR_SCALARS 1
    222 #define NDR_BUFFERS 2
     240#define NDR_SCALARS    0x100
     241#define NDR_BUFFERS    0x200
    223242
    224243/*
    225   flags passed to ndr_print_*()
     244  flags passed to ndr_print_*() and ndr pull/push for functions
     245  These are deliberately in a different range to the NDR_SCALARS/NDR_BUFFERS
     246  flags to catch mixups
    226247*/
    227 #define NDR_IN 1
    228 #define NDR_OUT 2
    229 #define NDR_BOTH 3
    230 #define NDR_SET_VALUES 4
     248#define NDR_IN         0x10
     249#define NDR_OUT        0x20
     250#define NDR_BOTH       0x30
     251#define NDR_SET_VALUES 0x40
     252
     253
     254#define NDR_PULL_CHECK_FLAGS(ndr, ndr_flags) do { \
     255        if ((ndr_flags) & ~(NDR_SCALARS|NDR_BUFFERS)) { \
     256                return ndr_pull_error(ndr, NDR_ERR_FLAGS, "Invalid pull struct ndr_flags 0x%x", ndr_flags); \
     257        } \
     258} while (0)
     259
     260#define NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags) do { \
     261        if ((ndr_flags) & ~(NDR_SCALARS|NDR_BUFFERS)) \
     262                return ndr_push_error(ndr, NDR_ERR_FLAGS, "Invalid push struct ndr_flags 0x%x", ndr_flags); \
     263} while (0)
     264
     265#define NDR_PULL_CHECK_FN_FLAGS(ndr, flags) do { \
     266        if ((flags) & ~(NDR_BOTH|NDR_SET_VALUES)) { \
     267                return ndr_pull_error(ndr, NDR_ERR_FLAGS, "Invalid fn pull flags 0x%x", flags); \
     268        } \
     269} while (0)
     270
     271#define NDR_PUSH_CHECK_FN_FLAGS(ndr, flags) do { \
     272        if ((flags) & ~(NDR_BOTH|NDR_SET_VALUES)) \
     273                return ndr_push_error(ndr, NDR_ERR_FLAGS, "Invalid fn push flags 0x%x", flags); \
     274} while (0)
    231275
    232276#define NDR_PULL_NEED_BYTES(ndr, n) do { \
    233277        if (unlikely((n) > ndr->data_size || ndr->offset + (n) > ndr->data_size)) { \
     278                if (ndr->flags & LIBNDR_FLAG_INCOMPLETE_BUFFER) { \
     279                        uint32_t _available = ndr->data_size - ndr->offset; \
     280                        uint32_t _missing = n - _available; \
     281                        ndr->relative_highest_offset = _missing; \
     282                } \
    234283                return ndr_pull_error(ndr, NDR_ERR_BUFSIZE, "Pull bytes %u (%s)", (unsigned)n, __location__); \
    235284        } \
     
    248297        } \
    249298        if (unlikely(ndr->offset > ndr->data_size)) {                   \
     299                if (ndr->flags & LIBNDR_FLAG_INCOMPLETE_BUFFER) { \
     300                        uint32_t _missing = ndr->offset - ndr->data_size; \
     301                        ndr->relative_highest_offset = _missing; \
     302                } \
    250303                return ndr_pull_error(ndr, NDR_ERR_BUFSIZE, "Pull align %u", (unsigned)n); \
    251304        } \
     
    403456void ndr_print_GUID(struct ndr_print *ndr, const char *name, const struct GUID *guid);
    404457bool ndr_syntax_id_equal(const struct ndr_syntax_id *i1, const struct ndr_syntax_id *i2);
     458char *ndr_syntax_id_to_string(TALLOC_CTX *mem_ctx, const struct ndr_syntax_id *id);
     459bool ndr_syntax_id_from_string(const char *s, struct ndr_syntax_id *id);
    405460enum ndr_err_code ndr_push_struct_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, const void *p, ndr_push_flags_fn_t fn);
    406461enum ndr_err_code ndr_push_union_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, void *p, uint32_t level, ndr_push_flags_fn_t fn);
     
    425480size_t ndr_align_size(uint32_t offset, size_t n);
    426481struct ndr_pull *ndr_pull_init_blob(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx);
     482enum ndr_err_code ndr_pull_append(struct ndr_pull *ndr, DATA_BLOB *blob);
     483enum ndr_err_code ndr_pull_pop(struct ndr_pull *ndr);
    427484enum ndr_err_code ndr_pull_advance(struct ndr_pull *ndr, uint32_t size);
    428485struct ndr_push *ndr_push_init_ctx(TALLOC_CTX *mem_ctx);
     
    430487enum ndr_err_code ndr_push_expand(struct ndr_push *ndr, uint32_t extra_size);
    431488void ndr_print_debug_helper(struct ndr_print *ndr, const char *format, ...) PRINTF_ATTRIBUTE(2,3);
     489void ndr_print_debugc_helper(struct ndr_print *ndr, const char *format, ...) PRINTF_ATTRIBUTE(2,3);
    432490void ndr_print_printf_helper(struct ndr_print *ndr, const char *format, ...) PRINTF_ATTRIBUTE(2,3);
    433491void ndr_print_string_helper(struct ndr_print *ndr, const char *format, ...) PRINTF_ATTRIBUTE(2,3);
    434492void ndr_print_debug(ndr_print_fn_t fn, const char *name, void *ptr);
     493void ndr_print_debugc(int dbgc_class, ndr_print_fn_t fn, const char *name, void *ptr);
    435494void ndr_print_union_debug(ndr_print_fn_t fn, const char *name, uint32_t level, void *ptr);
    436495void ndr_print_function_debug(ndr_print_function_t fn, const char *name, int flags, void *ptr);
  • trunk/server/librpc/ndr/ndr.c

    r918 r920  
    7878}
    7979
     80_PUBLIC_ enum ndr_err_code ndr_pull_append(struct ndr_pull *ndr, DATA_BLOB *blob)
     81{
     82        enum ndr_err_code ndr_err;
     83        DATA_BLOB b;
     84        uint32_t append = 0;
     85        bool ok;
     86
     87        if (blob->length == 0) {
     88                return NDR_ERR_SUCCESS;
     89        }
     90
     91        ndr_err = ndr_token_retrieve(&ndr->array_size_list, ndr, &append);
     92        if (ndr_err == NDR_ERR_TOKEN) {
     93                append = 0;
     94                ndr_err = NDR_ERR_SUCCESS;
     95        }
     96        NDR_CHECK(ndr_err);
     97
     98        if (ndr->data_size == 0) {
     99                ndr->data = NULL;
     100                append = UINT32_MAX;
     101        }
     102
     103        if (append == UINT32_MAX) {
     104                /*
     105                 * append == UINT32_MAX means that
     106                 * ndr->data is either NULL or a valid
     107                 * talloc child of ndr, which means
     108                 * we can use data_blob_append() without
     109                 * data_blob_talloc() of the existing callers data
     110                 */
     111                b = data_blob_const(ndr->data, ndr->data_size);
     112        } else {
     113                b = data_blob_talloc(ndr, ndr->data, ndr->data_size);
     114                if (b.data == NULL) {
     115                        return ndr_pull_error(ndr, NDR_ERR_ALLOC, "%s", __location__);
     116                }
     117        }
     118
     119        ok = data_blob_append(ndr, &b, blob->data, blob->length);
     120        if (!ok) {
     121                return ndr_pull_error(ndr, NDR_ERR_ALLOC, "%s", __location__);
     122        }
     123
     124        ndr->data = b.data;
     125        ndr->data_size = b.length;
     126
     127        return ndr_token_store(ndr, &ndr->array_size_list, ndr, UINT32_MAX);
     128}
     129
     130_PUBLIC_ enum ndr_err_code ndr_pull_pop(struct ndr_pull *ndr)
     131{
     132        uint32_t skip = 0;
     133        uint32_t append = 0;
     134
     135        if (ndr->relative_base_offset != 0) {
     136                return ndr_pull_error(ndr, NDR_ERR_RELATIVE,
     137                                      "%s", __location__);
     138        }
     139        if (ndr->relative_highest_offset != 0) {
     140                return ndr_pull_error(ndr, NDR_ERR_RELATIVE,
     141                                      "%s", __location__);
     142        }
     143        if (ndr->relative_list != NULL) {
     144                return ndr_pull_error(ndr, NDR_ERR_RELATIVE,
     145                                      "%s", __location__);
     146        }
     147        if (ndr->relative_base_list != NULL) {
     148                return ndr_pull_error(ndr, NDR_ERR_RELATIVE,
     149                                      "%s", __location__);
     150        }
     151
     152        /*
     153         * we need to keep up to 7 bytes
     154         * in order to get the aligment right.
     155         */
     156        skip = ndr->offset & 0xFFFFFFF8;
     157
     158        if (skip == 0) {
     159                return NDR_ERR_SUCCESS;
     160        }
     161
     162        ndr->offset -= skip;
     163        ndr->data_size -= skip;
     164
     165        append = ndr_token_peek(&ndr->array_size_list, ndr);
     166        if (append != UINT32_MAX) {
     167                /*
     168                 * here we assume, that ndr->data is not a
     169                 * talloc child of ndr.
     170                 */
     171                ndr->data += skip;
     172                return NDR_ERR_SUCCESS;
     173        }
     174
     175        memmove(ndr->data, ndr->data + skip, ndr->data_size);
     176
     177        ndr->data = talloc_realloc(ndr, ndr->data, uint8_t, ndr->data_size);
     178        if (ndr->data_size != 0 && ndr->data == NULL) {
     179                return ndr_pull_error(ndr, NDR_ERR_ALLOC, "%s", __location__);
     180        }
     181
     182        return NDR_ERR_SUCCESS;
     183}
     184
    80185/*
    81186  advance by 'size' bytes
     
    166271
    167272        return NDR_ERR_SUCCESS;
     273}
     274
     275_PUBLIC_ void ndr_print_debugc_helper(struct ndr_print *ndr, const char *format, ...)
     276{
     277        va_list ap;
     278        char *s = NULL;
     279        uint32_t i;
     280        int ret;
     281        int dbgc_class;
     282
     283        va_start(ap, format);
     284        ret = vasprintf(&s, format, ap);
     285        va_end(ap);
     286
     287        if (ret == -1) {
     288                return;
     289        }
     290
     291        dbgc_class = *(int *)ndr->private_data;
     292
     293        if (ndr->no_newline) {
     294                DEBUGADDC(dbgc_class, 1,("%s", s));
     295                free(s);
     296                return;
     297        }
     298
     299        for (i=0;i<ndr->depth;i++) {
     300                DEBUGADDC(dbgc_class, 1,("    "));
     301        }
     302
     303        DEBUGADDC(dbgc_class, 1,("%s\n", s));
     304        free(s);
    168305}
    169306
     
    236373                                                                  "\n");
    237374        }
     375}
     376
     377/*
     378  a useful helper function for printing idl structures via DEBUGC()
     379*/
     380_PUBLIC_ void ndr_print_debugc(int dbgc_class, ndr_print_fn_t fn, const char *name, void *ptr)
     381{
     382        struct ndr_print *ndr;
     383
     384        DEBUGC(dbgc_class, 1,(" "));
     385
     386        ndr = talloc_zero(NULL, struct ndr_print);
     387        if (!ndr) return;
     388        ndr->private_data = &dbgc_class;
     389        ndr->print = ndr_print_debugc_helper;
     390        ndr->depth = 1;
     391        ndr->flags = 0;
     392        fn(ndr, name, ptr);
     393        talloc_free(ndr);
    238394}
    239395
     
    403559        va_list ap;
    404560        int ret;
     561
     562        if (ndr->flags & LIBNDR_FLAG_INCOMPLETE_BUFFER) {
     563                switch (ndr_err) {
     564                case NDR_ERR_BUFSIZE:
     565                        return NDR_ERR_INCOMPLETE_BUFFER;
     566                default:
     567                        break;
     568                }
     569        }
    405570
    406571        va_start(ap, format);
     
    558723                break;
    559724        }
     725        case 0xFFFFFFFF:
     726                /*
     727                 * a shallow copy like subcontext
     728                 * useful for DCERPC pipe chunks.
     729                 */
     730                subndr = talloc_zero(ndr, struct ndr_pull);
     731                NDR_ERR_HAVE_NO_MEMORY(subndr);
     732
     733                subndr->flags           = ndr->flags;
     734                subndr->current_mem_ctx = ndr->current_mem_ctx;
     735                subndr->data            = ndr->data;
     736                subndr->offset          = ndr->offset;
     737                subndr->data_size       = ndr->data_size;
     738
     739                *_subndr = subndr;
     740                return NDR_ERR_SUCCESS;
     741
    560742        default:
    561743                return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT, "Bad subcontext (PULL) header_size %d",
     
    590772{
    591773        uint32_t advance;
    592         if (size_is >= 0) {
     774        uint32_t highest_ofs;
     775
     776        if (header_size == 0xFFFFFFFF) {
     777                advance = subndr->offset - ndr->offset;
     778        } else if (size_is >= 0) {
    593779                advance = size_is;
    594780        } else if (header_size > 0) {
     
    597783                advance = subndr->offset;
    598784        }
     785
     786        if (subndr->offset > ndr->relative_highest_offset) {
     787                highest_ofs = subndr->offset;
     788        } else {
     789                highest_ofs = subndr->relative_highest_offset;
     790        }
     791        if (!(subndr->flags & LIBNDR_FLAG_SUBCONTEXT_NO_UNREAD_BYTES)) {
     792                /*
     793                 * avoid an error unless SUBCONTEXT_NO_UNREAD_BYTES is specified
     794                 */
     795                highest_ofs = advance;
     796        }
     797        if (highest_ofs < advance) {
     798                return ndr_pull_error(subndr, NDR_ERR_UNREAD_BYTES,
     799                                      "not all bytes consumed ofs[%u] advance[%u]",
     800                                      highest_ofs, advance);
     801        }
     802
    599803        NDR_CHECK(ndr_pull_advance(ndr, advance));
    600804        return NDR_ERR_SUCCESS;
     
    14411645        { NDR_ERR_UNREAD_BYTES, "Unread Bytes" },
    14421646        { NDR_ERR_NDR64, "NDR64 assertion error" },
     1647        { NDR_ERR_INCOMPLETE_BUFFER, "Incomplete Buffer" },
    14431648        { 0, NULL }
    14441649};
  • trunk/server/librpc/ndr/ndr_basic.c

    r918 r920  
    6262_PUBLIC_ enum ndr_err_code ndr_pull_int8(struct ndr_pull *ndr, int ndr_flags, int8_t *v)
    6363{
     64        NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
    6465        NDR_PULL_NEED_BYTES(ndr, 1);
    6566        *v = (int8_t)CVAL(ndr->data, ndr->offset);
     
    7374_PUBLIC_ enum ndr_err_code ndr_pull_uint8(struct ndr_pull *ndr, int ndr_flags, uint8_t *v)
    7475{
     76        NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
    7577        NDR_PULL_NEED_BYTES(ndr, 1);
    7678        *v = CVAL(ndr->data, ndr->offset);
     
    8486_PUBLIC_ enum ndr_err_code ndr_pull_int16(struct ndr_pull *ndr, int ndr_flags, int16_t *v)
    8587{
     88        NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
    8689        NDR_PULL_ALIGN(ndr, 2);
    8790        NDR_PULL_NEED_BYTES(ndr, 2);
     
    9699_PUBLIC_ enum ndr_err_code ndr_pull_uint16(struct ndr_pull *ndr, int ndr_flags, uint16_t *v)
    97100{
     101        NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
    98102        NDR_PULL_ALIGN(ndr, 2);
    99103        NDR_PULL_NEED_BYTES(ndr, 2);
     
    108112_PUBLIC_ enum ndr_err_code ndr_pull_uint1632(struct ndr_pull *ndr, int ndr_flags, uint16_t *v)
    109113{
     114        NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
    110115        if (unlikely(ndr->flags & LIBNDR_FLAG_NDR64)) {
    111116                uint32_t v32 = 0;
     
    126131_PUBLIC_ enum ndr_err_code ndr_pull_int32(struct ndr_pull *ndr, int ndr_flags, int32_t *v)
    127132{
     133        NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
    128134        NDR_PULL_ALIGN(ndr, 4);
    129135        NDR_PULL_NEED_BYTES(ndr, 4);
     
    138144_PUBLIC_ enum ndr_err_code ndr_pull_uint32(struct ndr_pull *ndr, int ndr_flags, uint32_t *v)
    139145{
     146        NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
    140147        NDR_PULL_ALIGN(ndr, 4);
    141148        NDR_PULL_NEED_BYTES(ndr, 4);
     
    152159        uint64_t v64;
    153160        enum ndr_err_code err;
     161        NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
    154162        if (likely(!(ndr->flags & LIBNDR_FLAG_NDR64))) {
    155163                return ndr_pull_uint32(ndr, ndr_flags, v);
     
    170178_PUBLIC_ enum ndr_err_code ndr_pull_double(struct ndr_pull *ndr, int ndr_flags, double *v)
    171179{
     180        NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
    172181        NDR_PULL_ALIGN(ndr, 8);
    173182        NDR_PULL_NEED_BYTES(ndr, 8);
     
    218227_PUBLIC_ enum ndr_err_code ndr_pull_udlong(struct ndr_pull *ndr, int ndr_flags, uint64_t *v)
    219228{
     229        NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
    220230        NDR_PULL_ALIGN(ndr, 4);
    221231        NDR_PULL_NEED_BYTES(ndr, 8);
     
    231241_PUBLIC_ enum ndr_err_code ndr_pull_udlongr(struct ndr_pull *ndr, int ndr_flags, uint64_t *v)
    232242{
     243        NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
    233244        NDR_PULL_ALIGN(ndr, 4);
    234245        NDR_PULL_NEED_BYTES(ndr, 8);
     
    265276{
    266277        uintptr_t h;
     278        NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
    267279        NDR_PULL_ALIGN(ndr, sizeof(h));
    268280        NDR_PULL_NEED_BYTES(ndr, sizeof(h));
     
    279291{
    280292        uint32_t v;
     293        NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
    281294        NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v));
    282295        *status = NT_STATUS(v);
     
    303316{
    304317        uint32_t v;
     318        NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
    305319        NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v));
    306320        *status = W_ERROR(v);
     
    415429_PUBLIC_ enum ndr_err_code ndr_pull_array_uint8(struct ndr_pull *ndr, int ndr_flags, uint8_t *data, uint32_t n)
    416430{
     431        NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
    417432        if (!(ndr_flags & NDR_SCALARS)) {
    418433                return NDR_ERR_SUCCESS;
     
    426441_PUBLIC_ enum ndr_err_code ndr_push_int8(struct ndr_push *ndr, int ndr_flags, int8_t v)
    427442{
     443        NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
    428444        NDR_PUSH_NEED_BYTES(ndr, 1);
    429445        SCVAL(ndr->data, ndr->offset, (uint8_t)v);
     
    437453_PUBLIC_ enum ndr_err_code ndr_push_uint8(struct ndr_push *ndr, int ndr_flags, uint8_t v)
    438454{
     455        NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
    439456        NDR_PUSH_NEED_BYTES(ndr, 1);
    440457        SCVAL(ndr->data, ndr->offset, v);
     
    448465_PUBLIC_ enum ndr_err_code ndr_push_int16(struct ndr_push *ndr, int ndr_flags, int16_t v)
    449466{
     467        NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
    450468        NDR_PUSH_ALIGN(ndr, 2);
    451469        NDR_PUSH_NEED_BYTES(ndr, 2);
     
    460478_PUBLIC_ enum ndr_err_code ndr_push_uint16(struct ndr_push *ndr, int ndr_flags, uint16_t v)
    461479{
     480        NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
    462481        NDR_PUSH_ALIGN(ndr, 2);
    463482        NDR_PUSH_NEED_BYTES(ndr, 2);
     
    483502_PUBLIC_ enum ndr_err_code ndr_push_int32(struct ndr_push *ndr, int ndr_flags, int32_t v)
    484503{
     504        NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
    485505        NDR_PUSH_ALIGN(ndr, 4);
    486506        NDR_PUSH_NEED_BYTES(ndr, 4);
     
    495515_PUBLIC_ enum ndr_err_code ndr_push_uint32(struct ndr_push *ndr, int ndr_flags, uint32_t v)
    496516{
     517        NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
    497518        NDR_PUSH_ALIGN(ndr, 4);
    498519        NDR_PUSH_NEED_BYTES(ndr, 4);
     
    518539_PUBLIC_ enum ndr_err_code ndr_push_udlong(struct ndr_push *ndr, int ndr_flags, uint64_t v)
    519540{
     541        NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
    520542        NDR_PUSH_ALIGN(ndr, 4);
    521543        NDR_PUSH_NEED_BYTES(ndr, 8);
     
    531553_PUBLIC_ enum ndr_err_code ndr_push_udlongr(struct ndr_push *ndr, int ndr_flags, uint64_t v)
    532554{
     555        NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
    533556        NDR_PUSH_ALIGN(ndr, 4);
    534557        NDR_PUSH_NEED_BYTES(ndr, 8);
     
    564587_PUBLIC_ enum ndr_err_code ndr_push_double(struct ndr_push *ndr, int ndr_flags, double v)
    565588{
     589        NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
    566590        NDR_PUSH_ALIGN(ndr, 8);
    567591        NDR_PUSH_NEED_BYTES(ndr, 8);
     
    577601{
    578602        uintptr_t h = (intptr_t)v;
     603        NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
    579604        NDR_PUSH_ALIGN(ndr, sizeof(h));
    580605        NDR_PUSH_NEED_BYTES(ndr, sizeof(h));
     
    687712_PUBLIC_ enum ndr_err_code ndr_push_array_uint8(struct ndr_push *ndr, int ndr_flags, const uint8_t *data, uint32_t n)
    688713{
     714        NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
    689715        if (!(ndr_flags & NDR_SCALARS)) {
    690716                return NDR_ERR_SUCCESS;
     
    739765_PUBLIC_ enum ndr_err_code ndr_push_NTTIME(struct ndr_push *ndr, int ndr_flags, NTTIME t)
    740766{
     767        NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
    741768        NDR_CHECK(ndr_push_udlong(ndr, ndr_flags, t));
    742769        return NDR_ERR_SUCCESS;
     
    748775_PUBLIC_ enum ndr_err_code ndr_pull_NTTIME(struct ndr_pull *ndr, int ndr_flags, NTTIME *t)
    749776{
     777        NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
    750778        NDR_CHECK(ndr_pull_udlong(ndr, ndr_flags, t));
    751779        return NDR_ERR_SUCCESS;
     
    757785_PUBLIC_ enum ndr_err_code ndr_push_NTTIME_1sec(struct ndr_push *ndr, int ndr_flags, NTTIME t)
    758786{
     787        NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
    759788        t /= 10000000;
    760789        NDR_CHECK(ndr_push_hyper(ndr, ndr_flags, t));
     
    767796_PUBLIC_ enum ndr_err_code ndr_pull_NTTIME_1sec(struct ndr_pull *ndr, int ndr_flags, NTTIME *t)
    768797{
     798        NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
    769799        NDR_CHECK(ndr_pull_hyper(ndr, ndr_flags, t));
    770800        (*t) *= 10000000;
     
    777807_PUBLIC_ enum ndr_err_code ndr_pull_NTTIME_hyper(struct ndr_pull *ndr, int ndr_flags, NTTIME *t)
    778808{
     809        NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
    779810        NDR_CHECK(ndr_pull_hyper(ndr, ndr_flags, t));
    780811        return NDR_ERR_SUCCESS;
     
    786817_PUBLIC_ enum ndr_err_code ndr_push_NTTIME_hyper(struct ndr_push *ndr, int ndr_flags, NTTIME t)
    787818{
     819        NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
    788820        NDR_CHECK(ndr_push_hyper(ndr, ndr_flags, t));
    789821        return NDR_ERR_SUCCESS;
     
    815847_PUBLIC_ enum ndr_err_code ndr_push_uid_t(struct ndr_push *ndr, int ndr_flags, uid_t u)
    816848{
     849        NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
    817850        return ndr_push_hyper(ndr, NDR_SCALARS, (uint64_t)u);
    818851}
     
    840873_PUBLIC_ enum ndr_err_code ndr_push_gid_t(struct ndr_push *ndr, int ndr_flags, gid_t g)
    841874{
     875        NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
    842876        return ndr_push_hyper(ndr, NDR_SCALARS, (uint64_t)g);
    843877}
  • trunk/server/librpc/ndr/ndr_misc.c

    r414 r920  
    3636                && (i1->if_version == i2->if_version);
    3737}
     38
     39_PUBLIC_ char *ndr_syntax_id_to_string(TALLOC_CTX *mem_ctx, const struct ndr_syntax_id *id)
     40{
     41        return talloc_asprintf(mem_ctx,
     42                               "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x/0x%08x",
     43                               id->uuid.time_low, id->uuid.time_mid,
     44                               id->uuid.time_hi_and_version,
     45                               id->uuid.clock_seq[0],
     46                               id->uuid.clock_seq[1],
     47                               id->uuid.node[0], id->uuid.node[1],
     48                               id->uuid.node[2], id->uuid.node[3],
     49                               id->uuid.node[4], id->uuid.node[5],
     50                               (unsigned)id->if_version);
     51}
     52
     53_PUBLIC_ bool ndr_syntax_id_from_string(const char *s, struct ndr_syntax_id *id)
     54{
     55        int ret;
     56        size_t i;
     57        uint32_t time_low;
     58        uint32_t time_mid, time_hi_and_version;
     59        uint32_t clock_seq[2];
     60        uint32_t node[6];
     61        uint32_t if_version;
     62
     63        ret = sscanf(s,
     64                     "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x/0x%08x",
     65                     &time_low, &time_mid, &time_hi_and_version,
     66                     &clock_seq[0], &clock_seq[1],
     67                     &node[0], &node[1], &node[2], &node[3], &node[4], &node[5],
     68                     &if_version);
     69        if (ret != 12) {
     70                return false;
     71        }
     72
     73        id->uuid.time_low = time_low;
     74        id->uuid.time_mid = time_mid;
     75        id->uuid.time_hi_and_version = time_hi_and_version;
     76        id->uuid.clock_seq[0] = clock_seq[0];
     77        id->uuid.clock_seq[1] = clock_seq[1];
     78        for (i=0; i<6; i++) {
     79                id->uuid.node[i] = node[i];
     80        }
     81        id->if_version = if_version;
     82
     83        return true;
     84}
  • trunk/server/librpc/ndr/ndr_ntlmssp.c

    r918 r920  
    177177}
    178178
     179_PUBLIC_ struct AV_PAIR *ndr_ntlmssp_find_av(const struct AV_PAIR_LIST *av_list,
     180                                             enum ntlmssp_AvId AvId)
     181{
     182        struct AV_PAIR *res = NULL;
     183        uint32_t i = 0;
    179184
     185        for (i = 0; i < av_list->count; i++) {
     186                if (av_list->pair[i].AvId != AvId) {
     187                        continue;
     188                }
     189
     190                res = discard_const_p(struct AV_PAIR, &av_list->pair[i]);
     191                break;
     192        }
     193
     194        return res;
     195}
  • trunk/server/librpc/ndr/ndr_ntlmssp.h

    r918 r920  
    3232_PUBLIC_ void ndr_print_ntlmssp_Version(struct ndr_print *ndr, const char *name, const union ntlmssp_Version *r);
    3333
     34_PUBLIC_ struct AV_PAIR *ndr_ntlmssp_find_av(const struct AV_PAIR_LIST *av_list,
     35                                             enum ntlmssp_AvId AvId);
  • trunk/server/librpc/rpc/dcerpc_util.c

    r862 r920  
    2828#include "librpc/gen_ndr/ndr_dcerpc.h"
    2929#include "rpc_common.h"
     30#include "lib/util/bitmap.h"
    3031
    3132/* we need to be able to get/set the fragment length without doing a full
     
    9293* @return               - A NTSTATUS error code.
    9394*/
    94 NTSTATUS dcerpc_pull_auth_trailer(struct ncacn_packet *pkt,
     95NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt,
    9596                                  TALLOC_CTX *mem_ctx,
    96                                   DATA_BLOB *pkt_trailer,
     97                                  const DATA_BLOB *pkt_trailer,
    9798                                  struct dcerpc_auth *auth,
    98                                   uint32_t *auth_length,
     99                                  uint32_t *_auth_length,
    99100                                  bool auth_data_only)
    100101{
    101102        struct ndr_pull *ndr;
    102103        enum ndr_err_code ndr_err;
    103         uint32_t data_and_pad;
    104 
    105         data_and_pad = pkt_trailer->length
    106                         - (DCERPC_AUTH_TRAILER_LENGTH + pkt->auth_length);
    107 
    108         /* paranoia check for pad size. This would be caught anyway by
    109            the ndr_pull_advance() a few lines down, but it scared
    110            Jeremy enough for him to call me, so we might as well check
    111            it now, just to prevent someone posting a bogus YouTube
    112            video in the future.
    113         */
    114         if (data_and_pad > pkt_trailer->length) {
    115                 return NT_STATUS_INFO_LENGTH_MISMATCH;
    116         }
    117 
    118         *auth_length = pkt_trailer->length - data_and_pad;
     104        uint16_t data_and_pad;
     105        uint16_t auth_length;
     106        uint32_t tmp_length;
     107
     108        ZERO_STRUCTP(auth);
     109        if (_auth_length != NULL) {
     110                *_auth_length = 0;
     111        }
     112
     113        /* Paranoia checks for auth_length. The caller should check this... */
     114        if (pkt->auth_length == 0) {
     115                return NT_STATUS_INTERNAL_ERROR;
     116        }
     117
     118        /* Paranoia checks for auth_length. The caller should check this... */
     119        if (pkt->auth_length > pkt->frag_length) {
     120                return NT_STATUS_INTERNAL_ERROR;
     121        }
     122        tmp_length = DCERPC_NCACN_PAYLOAD_OFFSET;
     123        tmp_length += DCERPC_AUTH_TRAILER_LENGTH;
     124        tmp_length += pkt->auth_length;
     125        if (tmp_length > pkt->frag_length) {
     126                return NT_STATUS_INTERNAL_ERROR;
     127        }
     128        if (pkt_trailer->length > UINT16_MAX) {
     129                return NT_STATUS_INTERNAL_ERROR;
     130        }
     131
     132        auth_length = DCERPC_AUTH_TRAILER_LENGTH + pkt->auth_length;
     133        if (pkt_trailer->length < auth_length) {
     134                return NT_STATUS_RPC_PROTOCOL_ERROR;
     135        }
     136
     137        data_and_pad = pkt_trailer->length - auth_length;
    119138
    120139        ndr = ndr_pull_init_blob(pkt_trailer, mem_ctx);
     
    136155        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    137156                talloc_free(ndr);
     157                ZERO_STRUCTP(auth);
    138158                return ndr_map_error2ntstatus(ndr_err);
    139159        }
    140160
    141         if (auth_data_only && data_and_pad != auth->auth_pad_length) {
    142                 DEBUG(1, (__location__ ": WARNING: pad length mismatch. "
     161        if (data_and_pad < auth->auth_pad_length) {
     162                DEBUG(1, (__location__ ": ERROR: pad length mismatch. "
    143163                          "Calculated %u  got %u\n",
    144164                          (unsigned)data_and_pad,
    145165                          (unsigned)auth->auth_pad_length));
     166                talloc_free(ndr);
     167                ZERO_STRUCTP(auth);
     168                return NT_STATUS_RPC_PROTOCOL_ERROR;
     169        }
     170
     171        if (auth_data_only && data_and_pad != auth->auth_pad_length) {
     172                DEBUG(1, (__location__ ": ERROR: pad length mismatch. "
     173                          "Calculated %u  got %u\n",
     174                          (unsigned)data_and_pad,
     175                          (unsigned)auth->auth_pad_length));
     176                talloc_free(ndr);
     177                ZERO_STRUCTP(auth);
     178                return NT_STATUS_RPC_PROTOCOL_ERROR;
    146179        }
    147180
     
    151184        talloc_steal(mem_ctx, auth->credentials.data);
    152185        talloc_free(ndr);
     186
     187        if (_auth_length != NULL) {
     188                *_auth_length = auth_length;
     189        }
     190
     191        return NT_STATUS_OK;
     192}
     193
     194/**
     195* @brief        Verify the fields in ncacn_packet header.
     196*
     197* @param pkt            - The ncacn_packet strcuture
     198* @param ptype          - The expected PDU type
     199* @param max_auth_info  - The maximum size of a possible auth trailer
     200* @param required_flags - The required flags for the pdu.
     201* @param optional_flags - The possible optional flags for the pdu.
     202*
     203* @return               - A NTSTATUS error code.
     204*/
     205NTSTATUS dcerpc_verify_ncacn_packet_header(const struct ncacn_packet *pkt,
     206                                           enum dcerpc_pkt_type ptype,
     207                                           size_t max_auth_info,
     208                                           uint8_t required_flags,
     209                                           uint8_t optional_flags)
     210{
     211        if (pkt->rpc_vers != 5) {
     212                return NT_STATUS_RPC_PROTOCOL_ERROR;
     213        }
     214
     215        if (pkt->rpc_vers_minor != 0) {
     216                return NT_STATUS_RPC_PROTOCOL_ERROR;
     217        }
     218
     219        if (pkt->auth_length > pkt->frag_length) {
     220                return NT_STATUS_RPC_PROTOCOL_ERROR;
     221        }
     222
     223        if (pkt->ptype != ptype) {
     224                return NT_STATUS_RPC_PROTOCOL_ERROR;
     225        }
     226
     227        if (max_auth_info > UINT16_MAX) {
     228                return NT_STATUS_INTERNAL_ERROR;
     229        }
     230
     231        if (pkt->auth_length > 0) {
     232                size_t max_auth_length;
     233
     234                if (max_auth_info <= DCERPC_AUTH_TRAILER_LENGTH) {
     235                        return NT_STATUS_RPC_PROTOCOL_ERROR;
     236                }
     237                max_auth_length = max_auth_info - DCERPC_AUTH_TRAILER_LENGTH;
     238
     239                if (pkt->auth_length > max_auth_length) {
     240                        return NT_STATUS_RPC_PROTOCOL_ERROR;
     241                }
     242        }
     243
     244        if ((pkt->pfc_flags & required_flags) != required_flags) {
     245                return NT_STATUS_RPC_PROTOCOL_ERROR;
     246        }
     247        if (pkt->pfc_flags & ~(optional_flags|required_flags)) {
     248                return NT_STATUS_RPC_PROTOCOL_ERROR;
     249        }
     250
     251        if (pkt->drep[0] & ~DCERPC_DREP_LE) {
     252                return NT_STATUS_RPC_PROTOCOL_ERROR;
     253        }
     254        if (pkt->drep[1] != 0) {
     255                return NT_STATUS_RPC_PROTOCOL_ERROR;
     256        }
     257        if (pkt->drep[2] != 0) {
     258                return NT_STATUS_RPC_PROTOCOL_ERROR;
     259        }
     260        if (pkt->drep[3] != 0) {
     261                return NT_STATUS_RPC_PROTOCOL_ERROR;
     262        }
    153263
    154264        return NT_STATUS_OK;
     
    342452        return NT_STATUS_OK;
    343453}
     454
     455struct dcerpc_sec_vt_header2 dcerpc_sec_vt_header2_from_ncacn_packet(const struct ncacn_packet *pkt)
     456{
     457        struct dcerpc_sec_vt_header2 ret;
     458
     459        ZERO_STRUCT(ret);
     460        ret.ptype = pkt->ptype;
     461        memcpy(&ret.drep, pkt->drep, sizeof(ret.drep));
     462        ret.call_id = pkt->call_id;
     463
     464        switch (pkt->ptype) {
     465        case DCERPC_PKT_REQUEST:
     466                ret.context_id = pkt->u.request.context_id;
     467                ret.opnum      = pkt->u.request.opnum;
     468                break;
     469
     470        case DCERPC_PKT_RESPONSE:
     471                ret.context_id = pkt->u.response.context_id;
     472                break;
     473
     474        case DCERPC_PKT_FAULT:
     475                ret.context_id = pkt->u.fault.context_id;
     476                break;
     477
     478        default:
     479                break;
     480        }
     481
     482        return ret;
     483}
     484
     485bool dcerpc_sec_vt_header2_equal(const struct dcerpc_sec_vt_header2 *v1,
     486                                 const struct dcerpc_sec_vt_header2 *v2)
     487{
     488        if (v1->ptype != v2->ptype) {
     489                return false;
     490        }
     491
     492        if (memcmp(v1->drep, v2->drep, sizeof(v1->drep)) != 0) {
     493                return false;
     494        }
     495
     496        if (v1->call_id != v2->call_id) {
     497                return false;
     498        }
     499
     500        if (v1->context_id != v2->context_id) {
     501                return false;
     502        }
     503
     504        if (v1->opnum != v2->opnum) {
     505                return false;
     506        }
     507
     508        return true;
     509}
     510
     511static bool dcerpc_sec_vt_is_valid(const struct dcerpc_sec_verification_trailer *r)
     512{
     513        bool ret = false;
     514        TALLOC_CTX *frame = talloc_stackframe();
     515        struct bitmap *commands_seen;
     516        int i;
     517
     518        if (r->count.count == 0) {
     519                ret = true;
     520                goto done;
     521        }
     522
     523        if (memcmp(r->magic, DCERPC_SEC_VT_MAGIC, sizeof(r->magic)) != 0) {
     524                goto done;
     525        }
     526
     527        commands_seen = bitmap_talloc(frame, DCERPC_SEC_VT_COMMAND_ENUM + 1);
     528        if (commands_seen == NULL) {
     529                goto done;
     530        }
     531
     532        for (i=0; i < r->count.count; i++) {
     533                enum dcerpc_sec_vt_command_enum cmd =
     534                        r->commands[i].command & DCERPC_SEC_VT_COMMAND_ENUM;
     535
     536                if (bitmap_query(commands_seen, cmd)) {
     537                        /* Each command must appear at most once. */
     538                        goto done;
     539                }
     540                bitmap_set(commands_seen, cmd);
     541
     542                switch (cmd) {
     543                case DCERPC_SEC_VT_COMMAND_BITMASK1:
     544                case DCERPC_SEC_VT_COMMAND_PCONTEXT:
     545                case DCERPC_SEC_VT_COMMAND_HEADER2:
     546                        break;
     547                default:
     548                        if ((r->commands[i].u._unknown.length % 4) != 0) {
     549                                goto done;
     550                        }
     551                        break;
     552                }
     553        }
     554        ret = true;
     555done:
     556        TALLOC_FREE(frame);
     557        return ret;
     558}
     559
     560#define CHECK(msg, ok)                                          \
     561do {                                                            \
     562        if (!ok) {                                              \
     563                DEBUG(10, ("SEC_VT check %s failed\n", msg));   \
     564                return false;                                   \
     565        }                                                       \
     566} while(0)
     567
     568#define CHECK_SYNTAX(msg, s1, s2)                                       \
     569do {                                                            \
     570        if (!ndr_syntax_id_equal(&s1, &s2)) {                           \
     571                TALLOC_CTX *frame = talloc_stackframe();                \
     572                DEBUG(10, ("SEC_VT check %s failed: %s vs. %s\n", msg,  \
     573                           ndr_syntax_id_to_string(frame, &s1),         \
     574                           ndr_syntax_id_to_string(frame, &s1)));       \
     575                TALLOC_FREE(frame);                                     \
     576                return false;                                           \
     577        }                                                               \
     578} while(0)
     579
     580
     581bool dcerpc_sec_verification_trailer_check(
     582                const struct dcerpc_sec_verification_trailer *vt,
     583                const uint32_t *bitmask1,
     584                const struct dcerpc_sec_vt_pcontext *pcontext,
     585                const struct dcerpc_sec_vt_header2 *header2)
     586{
     587        size_t i;
     588
     589        if (!dcerpc_sec_vt_is_valid(vt)) {
     590                return false;
     591        }
     592
     593        for (i=0; i < vt->count.count; i++) {
     594                struct dcerpc_sec_vt *c = &vt->commands[i];
     595
     596                switch (c->command & DCERPC_SEC_VT_COMMAND_ENUM) {
     597                case DCERPC_SEC_VT_COMMAND_BITMASK1:
     598                        if (bitmask1 == NULL) {
     599                                CHECK("Bitmask1 must_process_command",
     600                                      !(c->command & DCERPC_SEC_VT_MUST_PROCESS));
     601                                break;
     602                        }
     603
     604                        if (c->u.bitmask1 & DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING) {
     605                                CHECK("Bitmask1 client_header_signing",
     606                                      *bitmask1 & DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING);
     607                        }
     608                        break;
     609
     610                case DCERPC_SEC_VT_COMMAND_PCONTEXT:
     611                        if (pcontext == NULL) {
     612                                CHECK("Pcontext must_process_command",
     613                                      !(c->command & DCERPC_SEC_VT_MUST_PROCESS));
     614                                break;
     615                        }
     616
     617                        CHECK_SYNTAX("Pcontect abstract_syntax",
     618                                     pcontext->abstract_syntax,
     619                                     c->u.pcontext.abstract_syntax);
     620                        CHECK_SYNTAX("Pcontext transfer_syntax",
     621                                     pcontext->transfer_syntax,
     622                                     c->u.pcontext.transfer_syntax);
     623                        break;
     624
     625                case DCERPC_SEC_VT_COMMAND_HEADER2: {
     626                        if (header2 == NULL) {
     627                                CHECK("Header2 must_process_command",
     628                                      !(c->command & DCERPC_SEC_VT_MUST_PROCESS));
     629                                break;
     630                        }
     631
     632                        CHECK("Header2", dcerpc_sec_vt_header2_equal(header2, &c->u.header2));
     633                        break;
     634                }
     635
     636                default:
     637                        CHECK("Unknown must_process_command",
     638                              !(c->command & DCERPC_SEC_VT_MUST_PROCESS));
     639                        break;
     640                }
     641        }
     642
     643        return true;
     644}
  • trunk/server/librpc/rpc/rpc_common.h

    r862 r920  
    159159* @return               - A NTSTATUS error code.
    160160*/
    161 NTSTATUS dcerpc_pull_auth_trailer(struct ncacn_packet *pkt,
     161NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt,
    162162                                  TALLOC_CTX *mem_ctx,
    163                                   DATA_BLOB *pkt_trailer,
     163                                  const DATA_BLOB *pkt_trailer,
    164164                                  struct dcerpc_auth *auth,
    165165                                  uint32_t *auth_length,
    166166                                  bool auth_data_only);
     167NTSTATUS dcerpc_verify_ncacn_packet_header(const struct ncacn_packet *pkt,
     168                                           enum dcerpc_pkt_type ptype,
     169                                           size_t max_auth_info,
     170                                           uint8_t required_flags,
     171                                           uint8_t optional_flags);
    167172struct tevent_req *dcerpc_read_ncacn_packet_send(TALLOC_CTX *mem_ctx,
    168173                                                 struct tevent_context *ev,
     
    297302                                    void *r_ptr);
    298303
     304/**
     305 * Extract header information from a ncacn_packet
     306 * as a dcerpc_sec_vt_header2 as used by the security verification trailer.
     307 *
     308 * @param[in] pkt a packet
     309 *
     310 * @return a dcerpc_sec_vt_header2
     311 */
     312struct dcerpc_sec_vt_header2 dcerpc_sec_vt_header2_from_ncacn_packet(const struct ncacn_packet *pkt);
     313
     314
     315/**
     316 * Test if two dcerpc_sec_vt_header2 structures are equal
     317 * without consideration of reserved fields.
     318 *
     319 * @param v1 a pointer to a dcerpc_sec_vt_header2 structure
     320 * @param v2 a pointer to a dcerpc_sec_vt_header2 structure
     321 *
     322 * @retval true if *v1 equals *v2
     323 */
     324bool dcerpc_sec_vt_header2_equal(const struct dcerpc_sec_vt_header2 *v1,
     325                                 const struct dcerpc_sec_vt_header2 *v2);
     326
     327/**
     328 * Check for consistency of the security verification trailer with the PDU header.
     329 * See <a href="http://msdn.microsoft.com/en-us/library/cc243559.aspx">MS-RPCE 2.2.2.13</a>.
     330 * A check with an empty trailer succeeds.
     331 *
     332 * @param[in] vt a pointer to the security verification trailer.
     333 * @param[in] bitmask1 which flags were negotiated on the connection.
     334 * @param[in] pcontext the syntaxes negotiatied for the presentation context.
     335 * @param[in] header2 some fields from the PDU header.
     336 *
     337 * @retval true on success.
     338 */
     339bool dcerpc_sec_verification_trailer_check(
     340                const struct dcerpc_sec_verification_trailer *vt,
     341                const uint32_t *bitmask1,
     342                const struct dcerpc_sec_vt_pcontext *pcontext,
     343                const struct dcerpc_sec_vt_header2 *header2);
     344
    299345#endif /* __DEFAULT_LIBRPC_RPCCOMMON_H__ */
  • trunk/server/librpc/wscript_build

    r918 r920  
    275275
    276276bld.SAMBA_SUBSYSTEM('NDR_DCERPC',
    277         source='gen_ndr/ndr_dcerpc.c',
     277        source='gen_ndr/ndr_dcerpc.c ndr/ndr_dcerpc.c',
    278278        public_deps='ndr',
     279        deps='bitmap',
    279280        public_headers='gen_ndr/ndr_dcerpc.h gen_ndr/dcerpc.h',
    280281        header_path= [ ('*gen_ndr*', 'gen_ndr') ],
Note: See TracChangeset for help on using the changeset viewer.