Ignore:
Timestamp:
Nov 24, 2016, 1:14:11 PM (9 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to version 4.4.3

Location:
vendor/current/librpc/rpc
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/librpc/rpc/binding.c

    r740 r988  
    88   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
    99   Copyright (C) Rafal Szczesniak 2006
     10   Copyright (C) Stefan Metzmacher 2014
    1011
    1112   This program is free software; you can redistribute it and/or modify
     
    3435
    3536#define MAX_PROTSEQ             10
     37
     38struct dcerpc_binding {
     39        enum dcerpc_transport_t transport;
     40        struct GUID object;
     41        const char *object_string;
     42        const char *host;
     43        const char *target_hostname;
     44        const char *target_principal;
     45        const char *endpoint;
     46        const char **options;
     47        uint32_t flags;
     48        uint32_t assoc_group_id;
     49        char assoc_group_string[11]; /* 0x3456789a + '\0' */
     50};
    3651
    3752static const struct {
     
    7489};
    7590
    76 static const struct {
     91static const struct ncacn_option {
    7792        const char *name;
    7893        uint32_t flag;
     
    8499        {"ntlm", DCERPC_AUTH_NTLM},
    85100        {"krb5", DCERPC_AUTH_KRB5},
     101        {"schannel", DCERPC_SCHANNEL},
    86102        {"validate", DCERPC_DEBUG_VALIDATE_BOTH},
    87103        {"print", DCERPC_DEBUG_PRINT_BOTH},
     
    89105        {"bigendian", DCERPC_PUSH_BIGENDIAN},
    90106        {"smb2", DCERPC_SMB2},
    91         {"hdrsign", DCERPC_HEADER_SIGNING},
    92107        {"ndr64", DCERPC_NDR64},
    93         {"localaddress", DCERPC_LOCALADDRESS}
    94108};
     109
     110static const struct ncacn_option *ncacn_option_by_name(const char *name)
     111{
     112        size_t i;
     113
     114        for (i=0; i<ARRAY_SIZE(ncacn_options); i++) {
     115                int ret;
     116
     117                ret = strcasecmp(ncacn_options[i].name, name);
     118                if (ret != 0) {
     119                        continue;
     120                }
     121
     122                return &ncacn_options[i];
     123        }
     124
     125        return NULL;
     126}
    95127
    96128const char *epm_floor_string(TALLOC_CTX *mem_ctx, struct epm_floor *epm_floor)
     
    106138                                char *uuidstr;
    107139
    108                                 if (GUID_equal(&syntax.uuid, &ndr_transfer_syntax.uuid)) {
     140                                if (GUID_equal(&syntax.uuid, &ndr_transfer_syntax_ndr.uuid)) {
    109141                                        return "NDR";
    110142                                }
    111143
    112                                 if (GUID_equal(&syntax.uuid, &ndr64_transfer_syntax.uuid)) {
     144                                if (GUID_equal(&syntax.uuid, &ndr_transfer_syntax_ndr64.uuid)) {
    113145                                        return "NDR64";
    114146                                }
     
    179211{
    180212        char *s = talloc_strdup(mem_ctx, "");
     213        char *o = s;
    181214        int i;
    182215        const char *t_name = NULL;
     216        bool option_section = false;
     217        const char *target_hostname = NULL;
    183218
    184219        if (b->transport != NCA_UNKNOWN) {
    185220                t_name = derpc_transport_string_by_transport(b->transport);
    186221                if (!t_name) {
    187                         return NULL;
    188                 }
    189         }
    190 
    191         if (!GUID_all_zero(&b->object.uuid)) {
    192                 s = talloc_asprintf(s, "%s@",
    193                                     GUID_string(mem_ctx, &b->object.uuid));
     222                        talloc_free(o);
     223                        return NULL;
     224                }
     225        }
     226
     227        if (!GUID_all_zero(&b->object)) {
     228                o = s;
     229                s = talloc_asprintf_append_buffer(s, "%s@",
     230                                    GUID_string(mem_ctx, &b->object));
     231                if (s == NULL) {
     232                        talloc_free(o);
     233                        return NULL;
     234                }
    194235        }
    195236
    196237        if (t_name != NULL) {
     238                o = s;
    197239                s = talloc_asprintf_append_buffer(s, "%s:", t_name);
    198240                if (s == NULL) {
     241                        talloc_free(o);
    199242                        return NULL;
    200243                }
     
    202245
    203246        if (b->host) {
     247                o = s;
    204248                s = talloc_asprintf_append_buffer(s, "%s", b->host);
    205         }
    206 
    207         if (!b->endpoint && !b->options && !b->flags) {
     249                if (s == NULL) {
     250                        talloc_free(o);
     251                        return NULL;
     252                }
     253        }
     254
     255        target_hostname = b->target_hostname;
     256        if (target_hostname != NULL && b->host != NULL) {
     257                if (strcmp(target_hostname, b->host) == 0) {
     258                        target_hostname = NULL;
     259                }
     260        }
     261
     262        if (b->endpoint) {
     263                option_section = true;
     264        } else if (target_hostname) {
     265                option_section = true;
     266        } else if (b->target_principal) {
     267                option_section = true;
     268        } else if (b->assoc_group_id != 0) {
     269                option_section = true;
     270        } else if (b->options) {
     271                option_section = true;
     272        } else if (b->flags) {
     273                option_section = true;
     274        }
     275
     276        if (!option_section) {
    208277                return s;
    209278        }
    210279
     280        o = s;
    211281        s = talloc_asprintf_append_buffer(s, "[");
     282        if (s == NULL) {
     283                talloc_free(o);
     284                return NULL;
     285        }
    212286
    213287        if (b->endpoint) {
     288                o = s;
    214289                s = talloc_asprintf_append_buffer(s, "%s", b->endpoint);
    215         }
    216 
    217         /* this is a *really* inefficent way of dealing with strings,
    218            but this is rarely called and the strings are always short,
    219            so I don't care */
     290                if (s == NULL) {
     291                        talloc_free(o);
     292                        return NULL;
     293                }
     294        }
     295
     296        for (i=0;i<ARRAY_SIZE(ncacn_options);i++) {
     297                if (!(b->flags & ncacn_options[i].flag)) {
     298                        continue;
     299                }
     300
     301                o = s;
     302                s = talloc_asprintf_append_buffer(s, ",%s", ncacn_options[i].name);
     303                if (s == NULL) {
     304                        talloc_free(o);
     305                        return NULL;
     306                }
     307        }
     308
     309        if (target_hostname) {
     310                o = s;
     311                s = talloc_asprintf_append_buffer(s, ",target_hostname=%s",
     312                                                  b->target_hostname);
     313                if (s == NULL) {
     314                        talloc_free(o);
     315                        return NULL;
     316                }
     317        }
     318
     319        if (b->target_principal) {
     320                o = s;
     321                s = talloc_asprintf_append_buffer(s, ",target_principal=%s",
     322                                                  b->target_principal);
     323                if (s == NULL) {
     324                        talloc_free(o);
     325                        return NULL;
     326                }
     327        }
     328
     329        if (b->assoc_group_id != 0) {
     330                o = s;
     331                s = talloc_asprintf_append_buffer(s, ",assoc_group_id=0x%08x",
     332                                                  b->assoc_group_id);
     333                if (s == NULL) {
     334                        talloc_free(o);
     335                        return NULL;
     336                }
     337        }
     338
    220339        for (i=0;b->options && b->options[i];i++) {
     340                o = s;
    221341                s = talloc_asprintf_append_buffer(s, ",%s", b->options[i]);
    222                 if (!s) return NULL;
    223         }
    224 
    225         for (i=0;i<ARRAY_SIZE(ncacn_options);i++) {
    226                 if (b->flags & ncacn_options[i].flag) {
    227                         if (ncacn_options[i].flag == DCERPC_LOCALADDRESS && b->localaddress) {
    228                                 s = talloc_asprintf_append_buffer(s, ",%s=%s", ncacn_options[i].name,
    229                                                                   b->localaddress);
    230                         } else {
    231                                 s = talloc_asprintf_append_buffer(s, ",%s", ncacn_options[i].name);
    232                         }
    233                         if (!s) return NULL;
    234                 }
    235         }
    236 
     342                if (s == NULL) {
     343                        talloc_free(o);
     344                        return NULL;
     345                }
     346        }
     347
     348        o = s;
    237349        s = talloc_asprintf_append_buffer(s, "]");
     350        if (s == NULL) {
     351                talloc_free(o);
     352                return NULL;
     353        }
    238354
    239355        return s;
     
    243359  parse a binding string into a dcerpc_binding structure
    244360*/
    245 _PUBLIC_ NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_binding **b_out)
    246 {
     361_PUBLIC_ NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *_s, struct dcerpc_binding **b_out)
     362{
     363        char *_t;
    247364        struct dcerpc_binding *b;
    248         char *options;
     365        char *s;
     366        char *options = NULL;
    249367        char *p;
    250         int i, j, comma_count;
     368        size_t i;
     369        NTSTATUS status;
    251370
    252371        b = talloc_zero(mem_ctx, struct dcerpc_binding);
     
    255374        }
    256375
     376        _t = talloc_strdup(b, _s);
     377        if (_t == NULL) {
     378                talloc_free(b);
     379                return NT_STATUS_NO_MEMORY;
     380        }
     381
     382        s = _t;
     383
     384        p = strchr(s, '[');
     385        if (p) {
     386                *p = '\0';
     387                options = p + 1;
     388                if (options[strlen(options)-1] != ']') {
     389                        talloc_free(b);
     390                        return NT_STATUS_INVALID_PARAMETER_MIX;
     391                }
     392                options[strlen(options)-1] = 0;
     393        }
     394
    257395        p = strchr(s, '@');
    258396
    259397        if (p && PTR_DIFF(p, s) == 36) { /* 36 is the length of a UUID */
    260                 NTSTATUS status;
    261                 DATA_BLOB blob = data_blob(s, 36);
    262                 status = GUID_from_data_blob(&blob, &b->object.uuid);
    263 
    264                 if (NT_STATUS_IS_ERR(status)) {
    265                         DEBUG(0, ("Failed parsing UUID\n"));
     398                *p = '\0';
     399
     400                status = dcerpc_binding_set_string_option(b, "object", s);
     401                if (!NT_STATUS_IS_OK(status)) {
     402                        talloc_free(b);
    266403                        return status;
    267404                }
    268405
    269406                s = p + 1;
    270         } else {
    271                 ZERO_STRUCT(b->object);
    272         }
    273 
    274         b->object.if_version = 0;
     407        }
    275408
    276409        p = strchr(s, ':');
     
    278411        if (p == NULL) {
    279412                b->transport = NCA_UNKNOWN;
     413        } else if (is_ipaddress_v6(s)) {
     414                b->transport = NCA_UNKNOWN;
    280415        } else {
    281                 char *type = talloc_strndup(mem_ctx, s, PTR_DIFF(p, s));
    282                 if (!type) {
     416                *p = '\0';
     417
     418                status = dcerpc_binding_set_string_option(b, "transport", s);
     419                if (!NT_STATUS_IS_OK(status)) {
     420                        talloc_free(b);
     421                        return status;
     422                }
     423
     424                s = p + 1;
     425        }
     426
     427        if (strlen(s) > 0) {
     428                status = dcerpc_binding_set_string_option(b, "host", s);
     429                if (!NT_STATUS_IS_OK(status)) {
     430                        talloc_free(b);
     431                        return status;
     432                }
     433
     434                b->target_hostname = talloc_strdup(b, b->host);
     435                if (b->target_hostname == NULL) {
     436                        talloc_free(b);
    283437                        return NT_STATUS_NO_MEMORY;
    284438                }
    285 
    286                 for (i=0;i<ARRAY_SIZE(transports);i++) {
    287                         if (strcasecmp(type, transports[i].name) == 0) {
    288                                 b->transport = transports[i].transport;
    289                                 break;
     439        }
     440
     441        for (i=0; options != NULL; i++) {
     442                const char *name = options;
     443                const char *value = NULL;
     444
     445                p = strchr(options, ',');
     446                if (p != NULL) {
     447                        *p = '\0';
     448                        options = p+1;
     449                } else {
     450                        options = NULL;
     451                }
     452
     453                p = strchr(name, '=');
     454                if (p != NULL) {
     455                        *p = '\0';
     456                        value = p + 1;
     457                }
     458
     459                if (value == NULL) {
     460                        /*
     461                         * If it's not a key=value pair
     462                         * it might be a ncacn_option
     463                         * or if it's the first option
     464                         * it's the endpoint.
     465                         */
     466                        const struct ncacn_option *no = NULL;
     467
     468                        value = name;
     469
     470                        no = ncacn_option_by_name(name);
     471                        if (no == NULL) {
     472                                if (i > 0) {
     473                                        /*
     474                                         * we don't allow unknown options
     475                                         */
     476                                        return NT_STATUS_INVALID_PARAMETER_MIX;
     477                                }
     478
     479                                /*
     480                                 * This is the endpoint
     481                                 */
     482                                name = "endpoint";
     483                                if (strlen(value) == 0) {
     484                                        value = NULL;
     485                                }
    290486                        }
    291487                }
    292488
    293                 if (i==ARRAY_SIZE(transports)) {
    294                         DEBUG(0,("Unknown dcerpc transport '%s'\n", type));
    295                         return NT_STATUS_INVALID_PARAMETER;
    296                 }
    297 
    298                 talloc_free(type);
    299 
    300                 s = p+1;
    301         }
    302 
    303         p = strchr(s, '[');
    304         if (p) {
    305                 b->host = talloc_strndup(b, s, PTR_DIFF(p, s));
    306                 options = talloc_strdup(mem_ctx, p+1);
    307                 if (options[strlen(options)-1] != ']') {
    308                         return NT_STATUS_INVALID_PARAMETER;
    309                 }
    310                 options[strlen(options)-1] = 0;
     489                status = dcerpc_binding_set_string_option(b, name, value);
     490                if (!NT_STATUS_IS_OK(status)) {
     491                        talloc_free(b);
     492                        return status;
     493                }
     494        }
     495
     496        talloc_free(_t);
     497        *b_out = b;
     498        return NT_STATUS_OK;
     499}
     500
     501_PUBLIC_ struct GUID dcerpc_binding_get_object(const struct dcerpc_binding *b)
     502{
     503        return b->object;
     504}
     505
     506_PUBLIC_ NTSTATUS dcerpc_binding_set_object(struct dcerpc_binding *b,
     507                                            struct GUID object)
     508{
     509        char *tmp = discard_const_p(char, b->object_string);
     510
     511        if (GUID_all_zero(&object)) {
     512                talloc_free(tmp);
     513                b->object_string = NULL;
     514                ZERO_STRUCT(b->object);
     515                return NT_STATUS_OK;
     516        }
     517
     518        b->object_string = GUID_string(b, &object);
     519        if (b->object_string == NULL) {
     520                b->object_string = tmp;
     521                return NT_STATUS_NO_MEMORY;
     522        }
     523        talloc_free(tmp);
     524
     525        b->object = object;
     526        return NT_STATUS_OK;
     527}
     528
     529_PUBLIC_ enum dcerpc_transport_t dcerpc_binding_get_transport(const struct dcerpc_binding *b)
     530{
     531        return b->transport;
     532}
     533
     534_PUBLIC_ NTSTATUS dcerpc_binding_set_transport(struct dcerpc_binding *b,
     535                                               enum dcerpc_transport_t transport)
     536{
     537        NTSTATUS status;
     538
     539        /*
     540         * TODO: we may want to check the transport value is
     541         * wellknown.
     542         */
     543        if (b->transport == transport) {
     544                return NT_STATUS_OK;
     545        }
     546
     547        /*
     548         * This implicitly resets the endpoint
     549         * as the endpoint is transport specific.
     550         *
     551         * It also resets the assoc group as it's
     552         * also endpoint specific.
     553         *
     554         * TODO: in future we may reset more options
     555         * here.
     556         */
     557        status = dcerpc_binding_set_string_option(b, "endpoint", NULL);
     558        if (!NT_STATUS_IS_OK(status)) {
     559                return status;
     560        }
     561
     562        b->assoc_group_id = 0;
     563
     564        b->transport = transport;
     565        return NT_STATUS_OK;
     566}
     567
     568_PUBLIC_ void dcerpc_binding_get_auth_info(const struct dcerpc_binding *b,
     569                                           enum dcerpc_AuthType *_auth_type,
     570                                           enum dcerpc_AuthLevel *_auth_level)
     571{
     572        enum dcerpc_AuthType auth_type;
     573        enum dcerpc_AuthLevel auth_level;
     574
     575        if (b->flags & DCERPC_AUTH_SPNEGO) {
     576                auth_type = DCERPC_AUTH_TYPE_SPNEGO;
     577        } else if (b->flags & DCERPC_AUTH_KRB5) {
     578                auth_type = DCERPC_AUTH_TYPE_KRB5;
     579        } else if (b->flags & DCERPC_SCHANNEL) {
     580                auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
     581        } else if (b->flags & DCERPC_AUTH_NTLM) {
     582                auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
    311583        } else {
    312                 b->host = talloc_strdup(b, s);
    313                 options = NULL;
    314         }
    315         if (!b->host) {
     584                auth_type = DCERPC_AUTH_TYPE_NONE;
     585        }
     586
     587        if (b->flags & DCERPC_SEAL) {
     588                auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
     589        } else if (b->flags & DCERPC_SIGN) {
     590                auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
     591        } else if (b->flags & DCERPC_CONNECT) {
     592                auth_level = DCERPC_AUTH_LEVEL_CONNECT;
     593        } else if (auth_type != DCERPC_AUTH_TYPE_NONE) {
     594                auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
     595        } else {
     596                auth_level = DCERPC_AUTH_LEVEL_NONE;
     597        }
     598
     599        if (_auth_type != NULL) {
     600                *_auth_type = auth_type;
     601        }
     602
     603        if (_auth_level != NULL) {
     604                *_auth_level = auth_level;
     605        }
     606}
     607
     608_PUBLIC_ uint32_t dcerpc_binding_get_assoc_group_id(const struct dcerpc_binding *b)
     609{
     610        return b->assoc_group_id;
     611}
     612
     613_PUBLIC_ NTSTATUS dcerpc_binding_set_assoc_group_id(struct dcerpc_binding *b,
     614                                                    uint32_t assoc_group_id)
     615{
     616        b->assoc_group_id = assoc_group_id;
     617        return NT_STATUS_OK;
     618}
     619
     620_PUBLIC_ struct ndr_syntax_id dcerpc_binding_get_abstract_syntax(const struct dcerpc_binding *b)
     621{
     622        const char *s = dcerpc_binding_get_string_option(b, "abstract_syntax");
     623        bool ok;
     624        struct ndr_syntax_id id;
     625
     626        if (s == NULL) {
     627                return ndr_syntax_id_null;
     628        }
     629
     630        ok = ndr_syntax_id_from_string(s, &id);
     631        if (!ok) {
     632                return ndr_syntax_id_null;
     633        }
     634
     635        return id;
     636}
     637
     638_PUBLIC_ NTSTATUS dcerpc_binding_set_abstract_syntax(struct dcerpc_binding *b,
     639                                                     const struct ndr_syntax_id *syntax)
     640{
     641        NTSTATUS status;
     642        char *s = NULL;
     643
     644        if (syntax == NULL) {
     645                status = dcerpc_binding_set_string_option(b, "abstract_syntax", NULL);
     646                if (!NT_STATUS_IS_OK(status)) {
     647                        return status;
     648                }
     649
     650                return NT_STATUS_OK;
     651        }
     652
     653        if (ndr_syntax_id_equal(&ndr_syntax_id_null, syntax)) {
     654                status = dcerpc_binding_set_string_option(b, "abstract_syntax", NULL);
     655                if (!NT_STATUS_IS_OK(status)) {
     656                        return status;
     657                }
     658
     659                return NT_STATUS_OK;
     660        }
     661
     662        s = ndr_syntax_id_to_string(b, syntax);
     663        if (s == NULL) {
    316664                return NT_STATUS_NO_MEMORY;
    317665        }
    318666
    319         b->target_hostname = b->host;
    320 
    321         b->options = NULL;
    322         b->flags = 0;
    323         b->assoc_group_id = 0;
    324         b->endpoint = NULL;
    325         b->localaddress = NULL;
    326 
    327         if (!options) {
    328                 *b_out = b;
    329                 return NT_STATUS_OK;
    330         }
    331 
    332         comma_count = count_chars(options, ',');
    333 
    334         b->options = talloc_array(b, const char *, comma_count+2);
    335         if (!b->options) {
     667        status = dcerpc_binding_set_string_option(b, "abstract_syntax", s);
     668        TALLOC_FREE(s);
     669        if (!NT_STATUS_IS_OK(status)) {
     670                return status;
     671        }
     672
     673        return NT_STATUS_OK;
     674}
     675
     676_PUBLIC_ const char *dcerpc_binding_get_string_option(const struct dcerpc_binding *b,
     677                                                      const char *name)
     678{
     679        struct {
     680                const char *name;
     681                const char *value;
     682#define _SPECIAL(x) { .name = #x, .value = b->x, }
     683        } specials[] = {
     684                { .name = "object", .value = b->object_string, },
     685                _SPECIAL(host),
     686                _SPECIAL(endpoint),
     687                _SPECIAL(target_hostname),
     688                _SPECIAL(target_principal),
     689#undef _SPECIAL
     690        };
     691        const struct ncacn_option *no = NULL;
     692        size_t name_len = strlen(name);
     693        size_t i;
     694        int ret;
     695
     696        ret = strcmp(name, "transport");
     697        if (ret == 0) {
     698                return derpc_transport_string_by_transport(b->transport);
     699        }
     700
     701        ret = strcmp(name, "assoc_group_id");
     702        if (ret == 0) {
     703                char *tmp = discard_const_p(char, b->assoc_group_string);
     704
     705                if (b->assoc_group_id == 0) {
     706                        return NULL;
     707                }
     708
     709                snprintf(tmp, sizeof(b->assoc_group_string),
     710                         "0x%08x", b->assoc_group_id);
     711                return (const char *)b->assoc_group_string;
     712        }
     713
     714        for (i=0; i < ARRAY_SIZE(specials); i++) {
     715                ret = strcmp(specials[i].name, name);
     716                if (ret != 0) {
     717                        continue;
     718                }
     719
     720                return specials[i].value;
     721        }
     722
     723        no = ncacn_option_by_name(name);
     724        if (no != NULL) {
     725                if (b->flags & no->flag) {
     726                        return no->name;
     727                }
     728
     729                return NULL;
     730        }
     731
     732        if (b->options == NULL) {
     733                return NULL;
     734        }
     735
     736        for (i=0; b->options[i]; i++) {
     737                const char *o = b->options[i];
     738                const char *vs = NULL;
     739
     740                ret = strncmp(name, o, name_len);
     741                if (ret != 0) {
     742                        continue;
     743                }
     744
     745                if (o[name_len] != '=') {
     746                        continue;
     747                }
     748
     749                vs = &o[name_len + 1];
     750
     751                return vs;
     752        }
     753
     754        return NULL;
     755}
     756
     757_PUBLIC_ char *dcerpc_binding_copy_string_option(TALLOC_CTX *mem_ctx,
     758                                                 const struct dcerpc_binding *b,
     759                                                 const char *name)
     760{
     761        const char *c = dcerpc_binding_get_string_option(b, name);
     762        char *v;
     763
     764        if (c == NULL) {
     765                errno = ENOENT;
     766                return NULL;
     767        }
     768
     769        v = talloc_strdup(mem_ctx, c);
     770        if (v == NULL) {
     771                errno = ENOMEM;
     772                return NULL;
     773        }
     774
     775        return v;
     776}
     777
     778_PUBLIC_ NTSTATUS dcerpc_binding_set_string_option(struct dcerpc_binding *b,
     779                                                   const char *name,
     780                                                   const char *value)
     781{
     782        struct {
     783                const char *name;
     784                const char **ptr;
     785#define _SPECIAL(x) { .name = #x, .ptr = &b->x, }
     786        } specials[] = {
     787                _SPECIAL(host),
     788                _SPECIAL(endpoint),
     789                _SPECIAL(target_hostname),
     790                _SPECIAL(target_principal),
     791#undef _SPECIAL
     792        };
     793        const struct ncacn_option *no = NULL;
     794        size_t name_len = strlen(name);
     795        const char *opt = NULL;
     796        char *tmp;
     797        size_t i;
     798        int ret;
     799
     800        /*
     801         * Note: value == NULL, means delete it.
     802         * value != NULL means add or reset.
     803         */
     804
     805        ret = strcmp(name, "transport");
     806        if (ret == 0) {
     807                enum dcerpc_transport_t t = dcerpc_transport_by_name(value);
     808
     809                if (t == NCA_UNKNOWN && value != NULL) {
     810                        return NT_STATUS_INVALID_PARAMETER_MIX;
     811                }
     812
     813                return dcerpc_binding_set_transport(b, t);
     814        }
     815
     816        ret = strcmp(name, "object");
     817        if (ret == 0) {
     818                NTSTATUS status;
     819                struct GUID uuid = GUID_zero();
     820
     821                if (value != NULL) {
     822                        DATA_BLOB blob;
     823                        blob = data_blob_string_const(value);
     824                        if (blob.length != 36) {
     825                                return NT_STATUS_INVALID_PARAMETER_MIX;
     826                        }
     827
     828                        status = GUID_from_data_blob(&blob, &uuid);
     829                        if (!NT_STATUS_IS_OK(status)) {
     830                                return status;
     831                        }
     832                }
     833
     834                return dcerpc_binding_set_object(b, uuid);
     835        }
     836
     837        ret = strcmp(name, "assoc_group_id");
     838        if (ret == 0) {
     839                uint32_t assoc_group_id = 0;
     840
     841                if (value != NULL) {
     842                        char c;
     843
     844                        ret = sscanf(value, "0x%08x%c", &assoc_group_id, &c);
     845                        if (ret != 1) {
     846                                return NT_STATUS_INVALID_PARAMETER_MIX;
     847                        }
     848                }
     849
     850                return dcerpc_binding_set_assoc_group_id(b, assoc_group_id);
     851        }
     852
     853        for (i=0; i < ARRAY_SIZE(specials); i++) {
     854                ret = strcmp(specials[i].name, name);
     855                if (ret != 0) {
     856                        continue;
     857                }
     858
     859                tmp = discard_const_p(char, *specials[i].ptr);
     860
     861                if (value == NULL) {
     862                        talloc_free(tmp);
     863                        *specials[i].ptr = NULL;
     864                        return NT_STATUS_OK;
     865                }
     866
     867                if (value[0] == '\0') {
     868                        return NT_STATUS_INVALID_PARAMETER_MIX;
     869                }
     870
     871                *specials[i].ptr = talloc_strdup(b, value);
     872                if (*specials[i].ptr == NULL) {
     873                        *specials[i].ptr = tmp;
     874                        return NT_STATUS_NO_MEMORY;
     875                }
     876                talloc_free(tmp);
     877
     878                return NT_STATUS_OK;
     879        }
     880
     881        no = ncacn_option_by_name(name);
     882        if (no != NULL) {
     883                if (value == NULL) {
     884                        b->flags &= ~no->flag;
     885                        return NT_STATUS_OK;
     886                }
     887
     888                ret = strcasecmp(no->name, value);
     889                if (ret != 0) {
     890                        return NT_STATUS_INVALID_PARAMETER_MIX;
     891                }
     892
     893                b->flags |= no->flag;
     894                return NT_STATUS_OK;
     895        }
     896
     897        for (i=0; b->options && b->options[i]; i++) {
     898                const char *o = b->options[i];
     899
     900                ret = strncmp(name, o, name_len);
     901                if (ret != 0) {
     902                        continue;
     903                }
     904
     905                if (o[name_len] != '=') {
     906                        continue;
     907                }
     908
     909                opt = o;
     910                break;
     911        }
     912
     913        if (opt == NULL) {
     914                const char **n;
     915
     916                if (value == NULL) {
     917                        return NT_STATUS_OK;
     918                }
     919
     920                n = talloc_realloc(b, b->options, const char *, i + 2);
     921                if (n == NULL) {
     922                        return NT_STATUS_NO_MEMORY;
     923                }
     924                n[i] = NULL;
     925                n[i + 1] = NULL;
     926                b->options = n;
     927        }
     928
     929        tmp = discard_const_p(char, opt);
     930
     931        if (value == NULL) {
     932                for (;b->options[i];i++) {
     933                        b->options[i] = b->options[i+1];
     934                }
     935                talloc_free(tmp);
     936                return NT_STATUS_OK;
     937        }
     938
     939        b->options[i] = talloc_asprintf(b->options, "%s=%s",
     940                                        name, value);
     941        if (b->options[i] == NULL) {
     942                b->options[i] = tmp;
    336943                return NT_STATUS_NO_MEMORY;
    337944        }
    338945
    339         for (i=0; (p = strchr(options, ',')); i++) {
    340                 b->options[i] = talloc_strndup(b, options, PTR_DIFF(p, options));
    341                 if (!b->options[i]) {
    342                         return NT_STATUS_NO_MEMORY;
    343                 }
    344                 options = p+1;
    345         }
    346         b->options[i] = options;
    347         b->options[i+1] = NULL;
    348 
    349         /* some options are pre-parsed for convenience */
    350         for (i=0;b->options[i];i++) {
    351                 for (j=0;j<ARRAY_SIZE(ncacn_options);j++) {
    352                         size_t opt_len = strlen(ncacn_options[j].name);
    353                         if (strncasecmp(ncacn_options[j].name, b->options[i], opt_len) == 0) {
    354                                 int k;
    355                                 char c = b->options[i][opt_len];
    356 
    357                                 if (ncacn_options[j].flag == DCERPC_LOCALADDRESS && c == '=') {
    358                                         b->localaddress = talloc_strdup(b, &b->options[i][opt_len+1]);
    359                                 } else if (c != 0) {
    360                                         continue;
    361                                 }
    362 
    363                                 b->flags |= ncacn_options[j].flag;
    364                                 for (k=i;b->options[k];k++) {
    365                                         b->options[k] = b->options[k+1];
    366                                 }
    367                                 i--;
    368                                 break;
    369                         }
    370                 }
    371         }
    372 
    373         if (b->options[0]) {
    374                 /* Endpoint is first option */
    375                 b->endpoint = b->options[0];
    376                 if (strlen(b->endpoint) == 0) b->endpoint = NULL;
    377 
    378                 for (i=0;b->options[i];i++) {
    379                         b->options[i] = b->options[i+1];
    380                 }
    381         }
    382 
    383         if (b->options[0] == NULL)
    384                 b->options = NULL;
    385 
    386         *b_out = b;
     946        return NT_STATUS_OK;
     947}
     948
     949_PUBLIC_ uint32_t dcerpc_binding_get_flags(const struct dcerpc_binding *b)
     950{
     951        return b->flags;
     952}
     953
     954_PUBLIC_ NTSTATUS dcerpc_binding_set_flags(struct dcerpc_binding *b,
     955                                           uint32_t additional,
     956                                           uint32_t clear)
     957{
     958        /*
     959         * TODO: in future we may want to reject invalid combinations
     960         */
     961        b->flags &= ~clear;
     962        b->flags |= additional;
     963
    387964        return NT_STATUS_OK;
    388965}
     
    4251002{
    4261003        DATA_BLOB blob;
    427         struct ndr_push *ndr = ndr_push_init_ctx(mem_ctx);
     1004        enum ndr_err_code ndr_err;
     1005        struct ndr_push *ndr;
     1006
     1007        ndr = ndr_push_init_ctx(mem_ctx);
     1008        if (ndr == NULL) {
     1009                return data_blob_null;
     1010        }
    4281011
    4291012        ndr->flags |= LIBNDR_FLAG_NOALIGN;
    4301013
    431         ndr_push_GUID(ndr, NDR_SCALARS | NDR_BUFFERS, &syntax->uuid);
    432         ndr_push_uint16(ndr, NDR_SCALARS, syntax->if_version);
     1014        ndr_err = ndr_push_GUID(ndr, NDR_SCALARS | NDR_BUFFERS, &syntax->uuid);
     1015        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     1016                return data_blob_null;
     1017        }
     1018        ndr_err = ndr_push_uint16(ndr, NDR_SCALARS, syntax->if_version);
     1019        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     1020                return data_blob_null;
     1021        }
    4331022
    4341023        blob = ndr_push_blob(ndr);
     
    4641053}
    4651054
    466 const char *dcerpc_floor_get_rhs_data(TALLOC_CTX *mem_ctx, struct epm_floor *epm_floor)
     1055char *dcerpc_floor_get_rhs_data(TALLOC_CTX *mem_ctx, struct epm_floor *epm_floor)
    4671056{
    4681057        switch (epm_floor->lhs.protocol) {
     
    5311120                                          const char *data)
    5321121{
     1122        if (data == NULL) {
     1123                data = "";
     1124        }
     1125
    5331126        switch (epm_floor->lhs.protocol) {
    5341127        case EPM_PROTOCOL_TCP:
     
    5451138
    5461139        case EPM_PROTOCOL_IP:
     1140                if (!is_ipaddress_v4(data)) {
     1141                        data = "0.0.0.0";
     1142                }
    5471143                epm_floor->rhs.ip.ipaddr = talloc_strdup(mem_ctx, data);
    5481144                NT_STATUS_HAVE_NO_MEMORY(epm_floor->rhs.ip.ipaddr);
     
    6311227                }
    6321228
    633                 for (j = 0; j < transports[i].num_protocols; j++) {
     1229                for (j = 0; j < transports[i].num_protocols && j < MAX_PROTSEQ; j++) {
    6341230                        if (transports[i].protseq[j] != tower->floors[j+2].lhs.protocol) {
    6351231                                break;
     
    6581254}
    6591255
     1256_PUBLIC_ enum dcerpc_transport_t dcerpc_transport_by_name(const char *name)
     1257{
     1258        size_t i;
     1259
     1260        if (name == NULL) {
     1261                return NCA_UNKNOWN;
     1262        }
     1263
     1264        for (i=0; i<ARRAY_SIZE(transports);i++) {
     1265                if (strcasecmp(name, transports[i].name) == 0) {
     1266                        return transports[i].transport;
     1267                }
     1268        }
     1269
     1270        return NCA_UNKNOWN;
     1271}
     1272
    6601273_PUBLIC_ NTSTATUS dcerpc_binding_from_tower(TALLOC_CTX *mem_ctx,
    6611274                                            struct epm_tower *tower,
     
    6631276{
    6641277        NTSTATUS status;
    665         struct dcerpc_binding *binding;
     1278        struct dcerpc_binding *b;
     1279        enum dcerpc_transport_t transport;
     1280        struct ndr_syntax_id abstract_syntax;
     1281        char *endpoint = NULL;
     1282        char *host = NULL;
    6661283
    6671284        /*
     
    6741291        }
    6751292
    676         binding = talloc_zero(mem_ctx, struct dcerpc_binding);
    677         NT_STATUS_HAVE_NO_MEMORY(binding);
    678 
    679         ZERO_STRUCT(binding->object);
    680         binding->options = NULL;
    681         binding->host = NULL;
    682         binding->target_hostname = NULL;
    683         binding->flags = 0;
    684         binding->assoc_group_id = 0;
    685 
    686         binding->transport = dcerpc_transport_by_tower(tower);
    687 
    688         if (binding->transport == (unsigned int)-1) {
     1293        status = dcerpc_parse_binding(mem_ctx, "", &b);
     1294        if (!NT_STATUS_IS_OK(status)) {
     1295                return status;
     1296        }
     1297
     1298        transport = dcerpc_transport_by_tower(tower);
     1299        if (transport == NCA_UNKNOWN) {
     1300                talloc_free(b);
    6891301                return NT_STATUS_NOT_SUPPORTED;
    6901302        }
    6911303
    692         /* Set object uuid */
    693         status = dcerpc_floor_get_lhs_data(&tower->floors[0], &binding->object);
    694 
     1304        status = dcerpc_binding_set_transport(b, transport);
    6951305        if (!NT_STATUS_IS_OK(status)) {
    696                 DEBUG(1, ("Error pulling object uuid and version: %s", nt_errstr(status)));
     1306                talloc_free(b);
    6971307                return status;
    6981308        }
    6991309
     1310        /* Set abstract syntax */
     1311        status = dcerpc_floor_get_lhs_data(&tower->floors[0], &abstract_syntax);
     1312        if (!NT_STATUS_IS_OK(status)) {
     1313                talloc_free(b);
     1314                return status;
     1315        }
     1316
     1317        status = dcerpc_binding_set_abstract_syntax(b, &abstract_syntax);
     1318        if (!NT_STATUS_IS_OK(status)) {
     1319                talloc_free(b);
     1320                return status;
     1321        }
     1322
    7001323        /* Ignore floor 1, it contains the NDR version info */
    7011324
    702         binding->options = NULL;
    703 
    7041325        /* Set endpoint */
     1326        errno = 0;
    7051327        if (tower->num_floors >= 4) {
    706                 binding->endpoint = dcerpc_floor_get_rhs_data(binding, &tower->floors[3]);
    707         } else {
    708                 binding->endpoint = NULL;
    709         }
     1328                endpoint = dcerpc_floor_get_rhs_data(b, &tower->floors[3]);
     1329        }
     1330        if (errno != 0) {
     1331                int saved_errno = errno;
     1332                talloc_free(b);
     1333                return map_nt_error_from_unix_common(saved_errno);
     1334        }
     1335
     1336        status = dcerpc_binding_set_string_option(b, "endpoint", endpoint);
     1337        if (!NT_STATUS_IS_OK(status)) {
     1338                talloc_free(b);
     1339                return status;
     1340        }
     1341        TALLOC_FREE(endpoint);
    7101342
    7111343        /* Set network address */
     1344        errno = 0;
    7121345        if (tower->num_floors >= 5) {
    713                 binding->host = dcerpc_floor_get_rhs_data(binding, &tower->floors[4]);
    714                 NT_STATUS_HAVE_NO_MEMORY(binding->host);
    715                 binding->target_hostname = binding->host;
    716         }
    717         *b_out = binding;
     1346                host = dcerpc_floor_get_rhs_data(b, &tower->floors[4]);
     1347        }
     1348        if (errno != 0) {
     1349                int saved_errno = errno;
     1350                talloc_free(b);
     1351                return map_nt_error_from_unix_common(saved_errno);
     1352        }
     1353
     1354        status = dcerpc_binding_set_string_option(b, "host", host);
     1355        if (!NT_STATUS_IS_OK(status)) {
     1356                talloc_free(b);
     1357                return status;
     1358        }
     1359        status = dcerpc_binding_set_string_option(b, "target_hostname", host);
     1360        if (!NT_STATUS_IS_OK(status)) {
     1361                talloc_free(b);
     1362                return status;
     1363        }
     1364        TALLOC_FREE(host);
     1365
     1366        *b_out = b;
    7181367        return NT_STATUS_OK;
    7191368}
     
    7351384        n->assoc_group_id = b->assoc_group_id;
    7361385
     1386        if (b->object_string != NULL) {
     1387                n->object_string = talloc_strdup(n, b->object_string);
     1388                if (n->object_string == NULL) {
     1389                        talloc_free(n);
     1390                        return NULL;
     1391                }
     1392        }
    7371393        if (b->host != NULL) {
    7381394                n->host = talloc_strdup(n, b->host);
     
    7541410                n->target_principal = talloc_strdup(n, b->target_principal);
    7551411                if (n->target_principal == NULL) {
    756                         talloc_free(n);
    757                         return NULL;
    758                 }
    759         }
    760 
    761         if (b->localaddress != NULL) {
    762                 n->localaddress = talloc_strdup(n, b->localaddress);
    763                 if (n->localaddress == NULL) {
    7641412                        talloc_free(n);
    7651413                        return NULL;
     
    8051453        const enum epm_protocol *protseq = NULL;
    8061454        int num_protocols = -1, i;
     1455        struct ndr_syntax_id abstract_syntax;
    8071456        NTSTATUS status;
    8081457
     
    8271476        tower->floors[0].lhs.protocol = EPM_PROTOCOL_UUID;
    8281477
    829         tower->floors[0].lhs.lhs_data = dcerpc_floor_pack_lhs_data(tower->floors, &binding->object);
     1478        abstract_syntax = dcerpc_binding_get_abstract_syntax(binding);
     1479        tower->floors[0].lhs.lhs_data = dcerpc_floor_pack_lhs_data(tower->floors,
     1480                                                                   &abstract_syntax);
    8301481
    8311482        if (!dcerpc_floor_pack_rhs_if_version_data(
    832                     tower->floors, &binding->object,
     1483                    tower->floors, &abstract_syntax,
    8331484                    &tower->floors[0].rhs.uuid.unknown)) {
    8341485                return NT_STATUS_NO_MEMORY;
     
    8391490
    8401491        tower->floors[1].lhs.lhs_data = dcerpc_floor_pack_lhs_data(tower->floors,
    841                                                                 &ndr_transfer_syntax);
     1492                                                                &ndr_transfer_syntax_ndr);
    8421493
    8431494        tower->floors[1].rhs.uuid.unknown = data_blob_talloc_zero(tower->floors, 2);
     
    8461497        for (i = 0; i < num_protocols; i++) {
    8471498                tower->floors[2 + i].lhs.protocol = protseq[i];
    848                 tower->floors[2 + i].lhs.lhs_data = data_blob_talloc(tower->floors, NULL, 0);
     1499                tower->floors[2 + i].lhs.lhs_data = data_blob_null;
    8491500                ZERO_STRUCT(tower->floors[2 + i].rhs);
    850                 dcerpc_floor_set_rhs_data(tower->floors, &tower->floors[2 + i], "");
     1501                status = dcerpc_floor_set_rhs_data(tower->floors,
     1502                                                   &tower->floors[2 + i],
     1503                                                   NULL);
     1504                if (!NT_STATUS_IS_OK(status)) {
     1505                        return status;
     1506                }
    8511507        }
    8521508
    8531509        /* The 4th floor contains the endpoint */
    8541510        if (num_protocols >= 2 && binding->endpoint) {
    855                 status = dcerpc_floor_set_rhs_data(tower->floors, &tower->floors[3], binding->endpoint);
    856                 if (NT_STATUS_IS_ERR(status)) {
     1511                status = dcerpc_floor_set_rhs_data(tower->floors,
     1512                                                   &tower->floors[3],
     1513                                                   binding->endpoint);
     1514                if (!NT_STATUS_IS_OK(status)) {
    8571515                        return status;
    8581516                }
     
    8611519        /* The 5th contains the network address */
    8621520        if (num_protocols >= 3 && binding->host) {
    863                 if (is_ipaddress(binding->host) ||
    864                     (binding->host[0] == '\\' && binding->host[1] == '\\')) {
    865                         status = dcerpc_floor_set_rhs_data(tower->floors, &tower->floors[4],
    866                                                            binding->host);
    867                 } else {
    868                         /* note that we don't attempt to resolve the
    869                            name here - when we get a hostname here we
    870                            are in the client code, and want to put in
    871                            a wildcard all-zeros IP for the server to
    872                            fill in */
    873                         status = dcerpc_floor_set_rhs_data(tower->floors, &tower->floors[4],
    874                                                            "0.0.0.0");
    875                 }
    876                 if (NT_STATUS_IS_ERR(status)) {
     1521                status = dcerpc_floor_set_rhs_data(tower->floors,
     1522                                                   &tower->floors[4],
     1523                                                   binding->host);
     1524                if (!NT_STATUS_IS_OK(status)) {
    8771525                        return status;
    8781526                }
  • vendor/current/librpc/rpc/binding_handle.c

    r740 r988  
    9999}
    100100
     101void dcerpc_binding_handle_auth_info(struct dcerpc_binding_handle *h,
     102                                     enum dcerpc_AuthType *auth_type,
     103                                     enum dcerpc_AuthLevel *auth_level)
     104{
     105        enum dcerpc_AuthType _auth_type;
     106        enum dcerpc_AuthLevel _auth_level;
     107
     108        if (auth_type == NULL) {
     109                auth_type = &_auth_type;
     110        }
     111
     112        if (auth_level == NULL) {
     113                auth_level = &_auth_level;
     114        }
     115
     116        *auth_type = DCERPC_AUTH_TYPE_NONE;
     117        *auth_level = DCERPC_AUTH_LEVEL_NONE;
     118
     119        if (h->ops->auth_info == NULL) {
     120                return;
     121        }
     122
     123        h->ops->auth_info(h, auth_type, auth_level);
     124}
     125
    101126struct dcerpc_binding_handle_raw_call_state {
    102127        const struct dcerpc_binding_handle_ops *ops;
     
    156181                                          &state->out_flags);
    157182        TALLOC_FREE(subreq);
    158         if (!NT_STATUS_IS_OK(error)) {
    159                 tevent_req_nterror(req, error);
     183        if (tevent_req_nterror(req, error)) {
    160184                return;
    161185        }
     
    201225        struct tevent_context *ev;
    202226        struct tevent_req *subreq;
    203         NTSTATUS status;
     227        NTSTATUS status = NT_STATUS_NO_MEMORY;
    204228
    205229        /*
     
    210234                ev = h->sync_ev;
    211235        } else {
    212                 ev = tevent_context_init(frame);
     236                ev = samba_tevent_context_init(frame);
    213237        }
    214238        if (ev == NULL) {
    215                 talloc_free(frame);
    216                 return NT_STATUS_NO_MEMORY;
     239                goto fail;
    217240        }
    218241
     
    223246                                                     in_length);
    224247        if (subreq == NULL) {
    225                 talloc_free(frame);
    226                 return NT_STATUS_NO_MEMORY;
    227         }
    228 
    229         if (!tevent_req_poll(subreq, ev)) {
    230                 status = map_nt_error_from_unix(errno);
    231                 talloc_free(frame);
    232                 return status;
     248                goto fail;
     249        }
     250
     251        if (!tevent_req_poll_ntstatus(subreq, ev, &status)) {
     252                goto fail;
    233253        }
    234254
     
    238258                                                     out_length,
    239259                                                     out_flags);
    240         if (!NT_STATUS_IS_OK(status)) {
    241                 talloc_free(frame);
    242                 return status;
    243         }
    244 
     260fail:
    245261        TALLOC_FREE(frame);
    246         return NT_STATUS_OK;
     262        return status;
    247263}
    248264
     
    289305        error = state->ops->disconnect_recv(subreq);
    290306        TALLOC_FREE(subreq);
    291         if (!NT_STATUS_IS_OK(error)) {
    292                 tevent_req_nterror(req, error);
     307        if (tevent_req_nterror(req, error)) {
    293308                return;
    294309        }
     
    442457                                                    &out_flags);
    443458        TALLOC_FREE(subreq);
    444         if (!NT_STATUS_IS_OK(error)) {
    445                 tevent_req_nterror(req, error);
     459        if (tevent_req_nterror(req, error)) {
    446460                return;
    447461        }
     
    495509NTSTATUS dcerpc_binding_handle_call_recv(struct tevent_req *req)
    496510{
    497         NTSTATUS error;
    498 
    499         if (tevent_req_is_nterror(req, &error)) {
    500                 tevent_req_received(req);
    501                 return error;
    502         }
    503 
    504         tevent_req_received(req);
    505         return NT_STATUS_OK;
     511        return tevent_req_simple_recv_ntstatus(req);
    506512}
    507513
     
    516522        struct tevent_context *ev;
    517523        struct tevent_req *subreq;
    518         NTSTATUS status;
     524        NTSTATUS status = NT_STATUS_NO_MEMORY;
    519525
    520526        /*
     
    525531                ev = h->sync_ev;
    526532        } else {
    527                 ev = tevent_context_init(frame);
     533                ev = samba_tevent_context_init(frame);
    528534        }
    529535        if (ev == NULL) {
    530                 talloc_free(frame);
    531                 return NT_STATUS_NO_MEMORY;
     536                goto fail;
    532537        }
    533538
     
    536541                                                 opnum, r_mem, r_ptr);
    537542        if (subreq == NULL) {
    538                 talloc_free(frame);
    539                 return NT_STATUS_NO_MEMORY;
    540         }
    541 
    542         if (!tevent_req_poll(subreq, ev)) {
    543                 status = map_nt_error_from_unix(errno);
    544                 talloc_free(frame);
    545                 return status;
     543                goto fail;
     544        }
     545
     546        if (!tevent_req_poll_ntstatus(subreq, ev, &status)) {
     547                goto fail;
    546548        }
    547549
    548550        status = dcerpc_binding_handle_call_recv(subreq);
    549         if (!NT_STATUS_IS_OK(status)) {
    550                 talloc_free(frame);
    551                 return status;
    552         }
    553 
     551fail:
    554552        TALLOC_FREE(frame);
    555         return NT_STATUS_OK;
    556 }
     553        return status;
     554}
  • vendor/current/librpc/rpc/dcerpc_error.c

    r740 r988  
    2727        const char *errstr;
    2828        uint32_t faultcode;
     29        NTSTATUS nt_status;
    2930};
    3031
    3132static const struct dcerpc_fault_table dcerpc_faults[] =
    3233{
    33 #define _FAULT_STR(x) { #x , x }
    34         _FAULT_STR(DCERPC_NCA_S_COMM_FAILURE),
    35         _FAULT_STR(DCERPC_NCA_S_OP_RNG_ERROR),
    36         _FAULT_STR(DCERPC_NCA_S_UNKNOWN_IF),
    37         _FAULT_STR(DCERPC_NCA_S_WRONG_BOOT_TIME),
    38         _FAULT_STR(DCERPC_NCA_S_YOU_CRASHED),
    39         _FAULT_STR(DCERPC_NCA_S_PROTO_ERROR),
    40         _FAULT_STR(DCERPC_NCA_S_OUT_ARGS_TOO_BIG),
    41         _FAULT_STR(DCERPC_NCA_S_SERVER_TOO_BUSY),
    42         _FAULT_STR(DCERPC_NCA_S_FAULT_STRING_TOO_LARGE),
    43         _FAULT_STR(DCERPC_NCA_S_UNSUPPORTED_TYPE),
    44         _FAULT_STR(DCERPC_NCA_S_FAULT_INT_DIV_BY_ZERO),
    45         _FAULT_STR(DCERPC_NCA_S_FAULT_ADDR_ERROR),
    46         _FAULT_STR(DCERPC_NCA_S_FAULT_FP_DIV_BY_ZERO),
    47         _FAULT_STR(DCERPC_NCA_S_FAULT_FP_UNDERFLOW),
    48         _FAULT_STR(DCERPC_NCA_S_FAULT_FP_OVERRFLOW),
    49         _FAULT_STR(DCERPC_NCA_S_FAULT_INVALID_TAG),
    50         _FAULT_STR(DCERPC_NCA_S_FAULT_INVALID_BOUND),
    51         _FAULT_STR(DCERPC_NCA_S_FAULT_RPC_VERSION_MISMATCH),
    52         _FAULT_STR(DCERPC_NCA_S_FAULT_UNSPEC_REJECT),
    53         _FAULT_STR(DCERPC_NCA_S_FAULT_BAD_ACTID),
    54         _FAULT_STR(DCERPC_NCA_S_FAULT_WHO_ARE_YOU_FAILED),
    55         _FAULT_STR(DCERPC_NCA_S_FAULT_MANAGER_NOT_ENTERED),
    56         _FAULT_STR(DCERPC_NCA_S_FAULT_CANCEL),
    57         _FAULT_STR(DCERPC_NCA_S_FAULT_ILL_INST),
    58         _FAULT_STR(DCERPC_NCA_S_FAULT_FP_ERROR),
    59         _FAULT_STR(DCERPC_NCA_S_FAULT_INT_OVERFLOW),
    60         _FAULT_STR(DCERPC_NCA_S_UNUSED_1C000011),
    61         _FAULT_STR(DCERPC_NCA_S_FAULT_UNSPEC),
    62         _FAULT_STR(DCERPC_NCA_S_FAULT_REMOTE_COMM_FAILURE),
    63         _FAULT_STR(DCERPC_NCA_S_FAULT_PIPE_EMPTY),
    64         _FAULT_STR(DCERPC_NCA_S_FAULT_PIPE_CLOSED),
    65         _FAULT_STR(DCERPC_NCA_S_FAULT_PIPE_ORDER),
    66         _FAULT_STR(DCERPC_NCA_S_FAULT_PIPE_DISCIPLINE),
    67         _FAULT_STR(DCERPC_NCA_S_FAULT_PIPE_COMM_ERROR),
    68         _FAULT_STR(DCERPC_NCA_S_FAULT_PIPE_MEMORY),
    69         _FAULT_STR(DCERPC_NCA_S_FAULT_CONTEXT_MISMATCH),
    70         _FAULT_STR(DCERPC_NCA_S_FAULT_REMOTE_NO_MEMORY),
    71         _FAULT_STR(DCERPC_NCA_S_INVALID_PRES_CONTEXT_ID),
    72         _FAULT_STR(DCERPC_NCA_S_UNSUPPORTED_AUTHN_LEVEL),
    73         _FAULT_STR(DCERPC_NCA_S_UNUSED_1C00001E),
    74         _FAULT_STR(DCERPC_NCA_S_INVALID_CHECKSUM),
    75         _FAULT_STR(DCERPC_NCA_S_INVALID_CRC),
    76         _FAULT_STR(DCERPC_NCA_S_FAULT_USER_DEFINED),
    77         _FAULT_STR(DCERPC_NCA_S_FAULT_TX_OPEN_FAILED),
    78         _FAULT_STR(DCERPC_NCA_S_FAULT_CODESET_CONV_ERROR),
    79         _FAULT_STR(DCERPC_NCA_S_FAULT_OBJECT_NOT_FOUND),
    80         _FAULT_STR(DCERPC_NCA_S_FAULT_NO_CLIENT_STUB),
     34#define _FAULT_STR(x, s) { .errstr = #x , .faultcode = x, .nt_status = s }
     35#define _FAULT_STR_NO_NT_MAPPING(x) _FAULT_STR(x, NT_STATUS_RPC_NOT_RPC_ERROR)
     36        _FAULT_STR(DCERPC_NCA_S_COMM_FAILURE, NT_STATUS_RPC_COMM_FAILURE),
     37        _FAULT_STR(DCERPC_NCA_S_OP_RNG_ERROR, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE),
     38        _FAULT_STR(DCERPC_NCA_S_UNKNOWN_IF, NT_STATUS_RPC_UNKNOWN_IF),
     39        _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_WRONG_BOOT_TIME),
     40        _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_YOU_CRASHED),
     41        _FAULT_STR(DCERPC_NCA_S_PROTO_ERROR, NT_STATUS_RPC_PROTOCOL_ERROR),
     42        _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_OUT_ARGS_TOO_BIG),
     43        _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_SERVER_TOO_BUSY),
     44        _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_STRING_TOO_LARGE),
     45        _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_UNSUPPORTED_TYPE),
     46        _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_ADDR_ERROR),
     47        _FAULT_STR(DCERPC_NCA_S_FAULT_FP_DIV_BY_ZERO, NT_STATUS_RPC_FP_DIV_ZERO),
     48        _FAULT_STR(DCERPC_NCA_S_FAULT_FP_UNDERFLOW, NT_STATUS_RPC_FP_UNDERFLOW),
     49        _FAULT_STR(DCERPC_NCA_S_FAULT_FP_OVERRFLOW, NT_STATUS_RPC_FP_OVERFLOW),
     50        _FAULT_STR(DCERPC_NCA_S_FAULT_INT_DIV_BY_ZERO, NT_STATUS_RPC_FP_DIV_ZERO),
     51        _FAULT_STR(DCERPC_NCA_S_FAULT_INT_OVERFLOW, NT_STATUS_RPC_FP_OVERFLOW),
     52        /*
     53         * What's the difference between NT_STATUS_RPC_INVALID_TAG
     54         * and NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE ???
     55         *
     56         * Our callers expect NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE.
     57         */
     58        _FAULT_STR(DCERPC_NCA_S_FAULT_INVALID_TAG, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE),
     59        _FAULT_STR(DCERPC_NCA_S_FAULT_INVALID_TAG, NT_STATUS_RPC_INVALID_TAG),
     60        _FAULT_STR(DCERPC_NCA_S_FAULT_INVALID_BOUND, NT_STATUS_RPC_INVALID_BOUND),
     61        _FAULT_STR(DCERPC_NCA_S_FAULT_RPC_VERSION_MISMATCH, NT_STATUS_RPC_PROTOCOL_ERROR),
     62        _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_UNSPEC_REJECT),
     63        _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_BAD_ACTID),
     64        _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_WHO_ARE_YOU_FAILED),
     65        _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_MANAGER_NOT_ENTERED),
     66        _FAULT_STR(DCERPC_NCA_S_FAULT_CANCEL, NT_STATUS_RPC_CALL_CANCELLED),
     67        _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_ILL_INST),
     68        _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_FP_ERROR),
     69        _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_UNUSED_1C000011),
     70        _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_UNSPEC),
     71        _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_REMOTE_COMM_FAILURE),
     72        _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_PIPE_EMPTY),
     73        _FAULT_STR(DCERPC_NCA_S_FAULT_PIPE_CLOSED, NT_STATUS_RPC_PIPE_CLOSED),
     74        _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_PIPE_ORDER),
     75        _FAULT_STR(DCERPC_NCA_S_FAULT_PIPE_DISCIPLINE, NT_STATUS_RPC_PIPE_DISCIPLINE_ERROR),
     76        _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_PIPE_COMM_ERROR),
     77        _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_PIPE_MEMORY),
     78        _FAULT_STR(DCERPC_NCA_S_FAULT_CONTEXT_MISMATCH, NT_STATUS_RPC_SS_CONTEXT_MISMATCH),
     79        _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_REMOTE_NO_MEMORY),
     80        _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_INVALID_PRES_CONTEXT_ID),
     81        _FAULT_STR(DCERPC_NCA_S_UNSUPPORTED_AUTHN_LEVEL, NT_STATUS_RPC_UNSUPPORTED_AUTHN_LEVEL),
     82        _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_UNUSED_1C00001E),
     83        _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_INVALID_CHECKSUM),
     84        _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_INVALID_CRC),
     85        _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_USER_DEFINED),
     86        _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_TX_OPEN_FAILED),
     87        _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_CODESET_CONV_ERROR),
     88        _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_OBJECT_NOT_FOUND),
     89        _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_NO_CLIENT_STUB),
     90        _FAULT_STR(DCERPC_FAULT_OTHER, NT_STATUS_RPC_CALL_FAILED),
     91        _FAULT_STR(DCERPC_FAULT_ACCESS_DENIED, NT_STATUS_ACCESS_DENIED),
     92        _FAULT_STR(DCERPC_FAULT_NO_CALL_ACTIVE, NT_STATUS_RPC_NO_CALL_ACTIVE),
     93        _FAULT_STR(DCERPC_FAULT_CANT_PERFORM, NT_STATUS_EPT_CANT_PERFORM_OP),
     94        _FAULT_STR(DCERPC_FAULT_OUT_OF_RESOURCES, NT_STATUS_RPC_OUT_OF_RESOURCES),
     95        _FAULT_STR(DCERPC_FAULT_BAD_STUB_DATA, NT_STATUS_RPC_BAD_STUB_DATA),
     96        _FAULT_STR(DCERPC_FAULT_SEC_PKG_ERROR, NT_STATUS_RPC_SEC_PKG_ERROR),
    8197        { NULL, 0 }
    8298#undef _FAULT_STR
     
    100116_PUBLIC_ NTSTATUS dcerpc_fault_to_nt_status(uint32_t fault_code)
    101117{
    102         /* TODO: add more mappings */
    103         switch (fault_code) {
    104         case DCERPC_FAULT_OP_RNG_ERROR:
    105                 return NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE;
    106         case DCERPC_FAULT_UNK_IF:
    107                 return NT_STATUS_RPC_UNKNOWN_IF;
    108         case DCERPC_FAULT_NDR:
    109                 return NT_STATUS_RPC_BAD_STUB_DATA;
    110         case DCERPC_FAULT_INVALID_TAG:
    111                 return NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE;
    112         case DCERPC_FAULT_CONTEXT_MISMATCH:
    113                 return NT_STATUS_RPC_SS_CONTEXT_MISMATCH;
    114         case DCERPC_FAULT_OTHER:
    115                 return NT_STATUS_RPC_CALL_FAILED;
    116         case DCERPC_FAULT_ACCESS_DENIED:
    117                 return NT_STATUS_ACCESS_DENIED;
    118         case DCERPC_FAULT_SEC_PKG_ERROR:
    119                 return NT_STATUS_RPC_SEC_PKG_ERROR;
     118        int idx = 0;
     119        WERROR werr = W_ERROR(fault_code);
     120
     121        if (fault_code == 0) {
     122                return NT_STATUS_RPC_PROTOCOL_ERROR;
    120123        }
    121124
    122         return NT_STATUS_RPC_PROTOCOL_ERROR;
     125        while (dcerpc_faults[idx].errstr != NULL) {
     126                if (dcerpc_faults[idx].faultcode == fault_code) {
     127                        return dcerpc_faults[idx].nt_status;
     128                }
     129                idx++;
     130        }
     131
     132        return werror_to_ntstatus(werr);
    123133}
    124134
     135_PUBLIC_ uint32_t dcerpc_fault_from_nt_status(NTSTATUS nt_status)
     136{
     137        int idx = 0;
     138        WERROR werr;
     139
     140        if (NT_STATUS_IS_OK(nt_status)) {
     141                return DCERPC_NCA_S_PROTO_ERROR;
     142        }
     143
     144        while (dcerpc_faults[idx].errstr != NULL) {
     145                if (NT_STATUS_EQUAL(dcerpc_faults[idx].nt_status, nt_status)) {
     146                        return dcerpc_faults[idx].faultcode;
     147                }
     148                idx++;
     149        }
     150
     151        werr = ntstatus_to_werror(nt_status);
     152
     153        return W_ERROR_V(werr);
     154}
  • vendor/current/librpc/rpc/dcerpc_util.c

    r919 r988  
    4747        } else {
    4848                return RSVAL(blob->data, DCERPC_FRAG_LEN_OFFSET);
    49         }
    50 }
    51 
    52 uint32_t dcerpc_get_call_id(const DATA_BLOB *blob)
    53 {
    54         if (CVAL(blob->data,DCERPC_DREP_OFFSET) & DCERPC_DREP_LE) {
    55                 return IVAL(blob->data, DCERPC_CALL_ID_OFFSET);
    56         } else {
    57                 return RIVAL(blob->data, DCERPC_CALL_ID_OFFSET);
    5849        }
    5950}
     
    329320
    330321        if (state->buffer.length == 0) {
    331                 /* first get enough to read the fragment length */
     322                /*
     323                 * first get enough to read the fragment length
     324                 *
     325                 * We read the full fixed ncacn_packet header
     326                 * in order to make wireshark happy with
     327                 * pcap files from socket_wrapper.
     328                 */
    332329                ofs = 0;
    333                 state->buffer.length = DCERPC_FRAG_LEN_OFFSET + 2;
     330                state->buffer.length = DCERPC_NCACN_PAYLOAD_OFFSET;
    334331                state->buffer.data = talloc_array(state, uint8_t,
    335332                                                  state->buffer.length);
     
    337334                        return -1;
    338335                }
    339         } else if (state->buffer.length == (DCERPC_FRAG_LEN_OFFSET + 2)) {
     336        } else if (state->buffer.length == DCERPC_NCACN_PAYLOAD_OFFSET) {
    340337                /* now read the fragment length and allocate the full buffer */
    341338                size_t frag_len = dcerpc_get_frag_length(&state->buffer);
     
    395392        TALLOC_FREE(subreq);
    396393        if (ret == -1) {
    397                 status = map_nt_error_from_unix(sys_errno);
     394                status = map_nt_error_from_unix_common(sys_errno);
    398395                tevent_req_nterror(req, status);
    399396                return;
     
    451448        tevent_req_received(req);
    452449        return NT_STATUS_OK;
     450}
     451
     452const char *dcerpc_default_transport_endpoint(TALLOC_CTX *mem_ctx,
     453                                              enum dcerpc_transport_t transport,
     454                                              const struct ndr_interface_table *table)
     455{
     456        NTSTATUS status;
     457        const char *p = NULL;
     458        const char *endpoint = NULL;
     459        int i;
     460        struct dcerpc_binding *default_binding = NULL;
     461        TALLOC_CTX *frame = talloc_stackframe();
     462
     463        /* Find one of the default pipes for this interface */
     464
     465        for (i = 0; i < table->endpoints->count; i++) {
     466                enum dcerpc_transport_t dtransport;
     467                const char *dendpoint;
     468
     469                status = dcerpc_parse_binding(frame, table->endpoints->names[i],
     470                                              &default_binding);
     471                if (!NT_STATUS_IS_OK(status)) {
     472                        continue;
     473                }
     474
     475                dtransport = dcerpc_binding_get_transport(default_binding);
     476                dendpoint = dcerpc_binding_get_string_option(default_binding,
     477                                                             "endpoint");
     478                if (dendpoint == NULL) {
     479                        TALLOC_FREE(default_binding);
     480                        continue;
     481                }
     482
     483                if (transport == NCA_UNKNOWN) {
     484                        transport = dtransport;
     485                }
     486
     487                if (transport != dtransport) {
     488                        TALLOC_FREE(default_binding);
     489                        continue;
     490                }
     491
     492                p = dendpoint;
     493                break;
     494        }
     495
     496        if (p == NULL) {
     497                goto done;
     498        }
     499
     500        /*
     501         * extract the pipe name without \\pipe from for example
     502         * ncacn_np:[\\pipe\\epmapper]
     503         */
     504        if (transport == NCACN_NP) {
     505                if (strncasecmp(p, "\\pipe\\", 6) == 0) {
     506                        p += 6;
     507                }
     508                if (strncmp(p, "\\", 1) == 0) {
     509                        p += 1;
     510                }
     511        }
     512
     513        endpoint = talloc_strdup(mem_ctx, p);
     514
     515 done:
     516        talloc_free(frame);
     517        return endpoint;
    453518}
    454519
     
    558623}
    559624
    560 #define CHECK(msg, ok)                                          \
    561 do {                                                            \
    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)                                       \
    569 do {                                                            \
    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 
     625static bool dcerpc_sec_vt_bitmask_check(const uint32_t *bitmask1,
     626                                        struct dcerpc_sec_vt *c)
     627{
     628        if (bitmask1 == NULL) {
     629                if (c->command & DCERPC_SEC_VT_MUST_PROCESS) {
     630                        DEBUG(10, ("SEC_VT check Bitmask1 must_process_command "
     631                                   "failed\n"));
     632                        return false;
     633                }
     634
     635                return true;
     636        }
     637
     638        if ((c->u.bitmask1 & DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING)
     639         && (!(*bitmask1 & DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING))) {
     640                DEBUG(10, ("SEC_VT check Bitmask1 client_header_signing "
     641                           "failed\n"));
     642                return false;
     643        }
     644        return true;
     645}
     646
     647static bool dcerpc_sec_vt_pctx_check(const struct dcerpc_sec_vt_pcontext *pcontext,
     648                                     struct dcerpc_sec_vt *c)
     649{
     650        TALLOC_CTX *mem_ctx;
     651        bool ok;
     652
     653        if (pcontext == NULL) {
     654                if (c->command & DCERPC_SEC_VT_MUST_PROCESS) {
     655                        DEBUG(10, ("SEC_VT check Pcontext must_process_command "
     656                                   "failed\n"));
     657                        return false;
     658                }
     659
     660                return true;
     661        }
     662
     663        mem_ctx = talloc_stackframe();
     664        ok = ndr_syntax_id_equal(&pcontext->abstract_syntax,
     665                                 &c->u.pcontext.abstract_syntax);
     666        if (!ok) {
     667                DEBUG(10, ("SEC_VT check pcontext abstract_syntax failed: "
     668                           "%s vs. %s\n",
     669                           ndr_syntax_id_to_string(mem_ctx,
     670                                        &pcontext->abstract_syntax),
     671                           ndr_syntax_id_to_string(mem_ctx,
     672                                        &c->u.pcontext.abstract_syntax)));
     673                goto err_ctx_free;
     674        }
     675        ok = ndr_syntax_id_equal(&pcontext->transfer_syntax,
     676                                 &c->u.pcontext.transfer_syntax);
     677        if (!ok) {
     678                DEBUG(10, ("SEC_VT check pcontext transfer_syntax failed: "
     679                           "%s vs. %s\n",
     680                           ndr_syntax_id_to_string(mem_ctx,
     681                                        &pcontext->transfer_syntax),
     682                           ndr_syntax_id_to_string(mem_ctx,
     683                                        &c->u.pcontext.transfer_syntax)));
     684                goto err_ctx_free;
     685        }
     686
     687        ok = true;
     688err_ctx_free:
     689        talloc_free(mem_ctx);
     690        return ok;
     691}
     692
     693static bool dcerpc_sec_vt_hdr2_check(const struct dcerpc_sec_vt_header2 *header2,
     694                                     struct dcerpc_sec_vt *c)
     695{
     696        if (header2 == NULL) {
     697                if (c->command & DCERPC_SEC_VT_MUST_PROCESS) {
     698                        DEBUG(10, ("SEC_VT check Header2 must_process_command failed\n"));
     699                        return false;
     700                }
     701
     702                return true;
     703        }
     704
     705        if (!dcerpc_sec_vt_header2_equal(header2, &c->u.header2)) {
     706                DEBUG(10, ("SEC_VT check Header2 failed\n"));
     707                return false;
     708        }
     709
     710        return true;
     711}
    580712
    581713bool dcerpc_sec_verification_trailer_check(
     
    592724
    593725        for (i=0; i < vt->count.count; i++) {
     726                bool ok;
    594727                struct dcerpc_sec_vt *c = &vt->commands[i];
    595728
    596729                switch (c->command & DCERPC_SEC_VT_COMMAND_ENUM) {
    597730                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);
     731                        ok = dcerpc_sec_vt_bitmask_check(bitmask1, c);
     732                        if (!ok) {
     733                                return false;
    607734                        }
    608735                        break;
    609736
    610737                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;
     738                        ok = dcerpc_sec_vt_pctx_check(pcontext, c);
     739                        if (!ok) {
     740                                return false;
    615741                        }
    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);
    623742                        break;
    624743
    625744                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;
     745                        ok = dcerpc_sec_vt_hdr2_check(header2, c);
     746                        if (!ok) {
     747                                return false;
    630748                        }
    631 
    632                         CHECK("Header2", dcerpc_sec_vt_header2_equal(header2, &c->u.header2));
    633749                        break;
    634750                }
    635751
    636752                default:
    637                         CHECK("Unknown must_process_command",
    638                               !(c->command & DCERPC_SEC_VT_MUST_PROCESS));
     753                        if (c->command & DCERPC_SEC_VT_MUST_PROCESS) {
     754                                DEBUG(10, ("SEC_VT check Unknown must_process_command failed\n"));
     755                                return false;
     756                        }
     757
    639758                        break;
    640759                }
     
    643762        return true;
    644763}
     764
     765static const struct ndr_syntax_id dcerpc_bind_time_features_prefix  = {
     766        .uuid = {
     767                .time_low = 0x6cb71c2c,
     768                .time_mid = 0x9812,
     769                .time_hi_and_version = 0x4540,
     770                .clock_seq = {0x00, 0x00},
     771                .node = {0x00,0x00,0x00,0x00,0x00,0x00}
     772        },
     773        .if_version = 1,
     774};
     775
     776bool dcerpc_extract_bind_time_features(struct ndr_syntax_id s, uint64_t *_features)
     777{
     778        uint8_t values[8];
     779        uint64_t features = 0;
     780
     781        values[0] = s.uuid.clock_seq[0];
     782        values[1] = s.uuid.clock_seq[1];
     783        values[2] = s.uuid.node[0];
     784        values[3] = s.uuid.node[1];
     785        values[4] = s.uuid.node[2];
     786        values[5] = s.uuid.node[3];
     787        values[6] = s.uuid.node[4];
     788        values[7] = s.uuid.node[5];
     789
     790        ZERO_STRUCT(s.uuid.clock_seq);
     791        ZERO_STRUCT(s.uuid.node);
     792
     793        if (!ndr_syntax_id_equal(&s, &dcerpc_bind_time_features_prefix)) {
     794                if (_features != NULL) {
     795                        *_features = 0;
     796                }
     797                return false;
     798        }
     799
     800        features = BVAL(values, 0);
     801
     802        if (_features != NULL) {
     803                *_features = features;
     804        }
     805
     806        return true;
     807}
     808
     809struct ndr_syntax_id dcerpc_construct_bind_time_features(uint64_t features)
     810{
     811        struct ndr_syntax_id s = dcerpc_bind_time_features_prefix;
     812        uint8_t values[8];
     813
     814        SBVAL(values, 0, features);
     815
     816        s.uuid.clock_seq[0] = values[0];
     817        s.uuid.clock_seq[1] = values[1];
     818        s.uuid.node[0]      = values[2];
     819        s.uuid.node[1]      = values[3];
     820        s.uuid.node[2]      = values[4];
     821        s.uuid.node[3]      = values[5];
     822        s.uuid.node[4]      = values[6];
     823        s.uuid.node[5]      = values[7];
     824
     825        return s;
     826}
  • vendor/current/librpc/rpc/rpc_common.h

    r919 r988  
    2222#ifndef __DEFAULT_LIBRPC_RPCCOMMON_H__
    2323#define __DEFAULT_LIBRPC_RPCCOMMON_H__
     24
     25#include "gen_ndr/dcerpc.h"
     26#include "lib/util/attr.h"
    2427
    2528struct dcerpc_binding_handle;
     
    4144
    4245/** this describes a binding to a particular transport/pipe */
    43 struct dcerpc_binding {
    44         enum dcerpc_transport_t transport;
    45         struct ndr_syntax_id object;
    46         const char *host;
    47         const char *target_hostname;
    48         const char *target_principal;
    49         const char *endpoint;
    50         const char **options;
    51         const char *localaddress;
    52         uint32_t flags;
    53         uint32_t assoc_group_id;
    54 };
     46struct dcerpc_binding;
    5547
    5648/* dcerpc pipe flags */
     
    9991#define DCERPC_CONCURRENT_MULTIPLEX     (1<<19)
    10092
    101 /* this triggers the DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN flag in the bind request */
     93/* this indicates DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN flag was negotiated */
    10294#define DCERPC_HEADER_SIGNING          (1<<20)
    10395
     
    10597#define DCERPC_NDR64                   (1<<21)
    10698
    107 /* specify binding interface */
    108 #define DCERPC_LOCALADDRESS            (1<<22)
     99/* handle upgrades or downgrades automatically */
     100#define DCERPC_SCHANNEL_AUTO           (1<<23)
     101
     102/* use aes schannel with hmac-sh256 session key */
     103#define DCERPC_SCHANNEL_AES            (1<<24)
     104
     105/* this triggers the DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN flag in the bind request */
     106#define DCERPC_PROPOSE_HEADER_SIGNING          (1<<25)
    109107
    110108/* The following definitions come from ../librpc/rpc/dcerpc_error.c  */
     
    112110const char *dcerpc_errstr(TALLOC_CTX *mem_ctx, uint32_t fault_code);
    113111NTSTATUS dcerpc_fault_to_nt_status(uint32_t fault_code);
     112uint32_t dcerpc_fault_from_nt_status(NTSTATUS nt_status);
    114113
    115114/* The following definitions come from ../librpc/rpc/binding.c  */
    116115
    117116const char *epm_floor_string(TALLOC_CTX *mem_ctx, struct epm_floor *epm_floor);
    118 const char *dcerpc_floor_get_rhs_data(TALLOC_CTX *mem_ctx, struct epm_floor *epm_floor);
     117char *dcerpc_floor_get_rhs_data(TALLOC_CTX *mem_ctx, struct epm_floor *epm_floor);
    119118enum dcerpc_transport_t dcerpc_transport_by_endpoint_protocol(int prot);
    120119struct dcerpc_binding *dcerpc_binding_dup(TALLOC_CTX *mem_ctx,
     
    128127NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_binding **b_out);
    129128char *dcerpc_binding_string(TALLOC_CTX *mem_ctx, const struct dcerpc_binding *b);
     129struct GUID dcerpc_binding_get_object(const struct dcerpc_binding *b);
     130NTSTATUS dcerpc_binding_set_object(struct dcerpc_binding *b,
     131                                   struct GUID object);
     132enum dcerpc_transport_t dcerpc_binding_get_transport(const struct dcerpc_binding *b);
     133NTSTATUS dcerpc_binding_set_transport(struct dcerpc_binding *b,
     134                                      enum dcerpc_transport_t transport);
     135void dcerpc_binding_get_auth_info(const struct dcerpc_binding *b,
     136                                  enum dcerpc_AuthType *_auth_type,
     137                                  enum dcerpc_AuthLevel *_auth_level);
     138uint32_t dcerpc_binding_get_assoc_group_id(const struct dcerpc_binding *b);
     139NTSTATUS dcerpc_binding_set_assoc_group_id(struct dcerpc_binding *b,
     140                                           uint32_t assoc_group_id);
     141struct ndr_syntax_id dcerpc_binding_get_abstract_syntax(const struct dcerpc_binding *b);
     142NTSTATUS dcerpc_binding_set_abstract_syntax(struct dcerpc_binding *b,
     143                                            const struct ndr_syntax_id *syntax);
     144const char *dcerpc_binding_get_string_option(const struct dcerpc_binding *b,
     145                                             const char *name);
     146char *dcerpc_binding_copy_string_option(TALLOC_CTX *mem_ctx,
     147                                        const struct dcerpc_binding *b,
     148                                        const char *name);
     149NTSTATUS dcerpc_binding_set_string_option(struct dcerpc_binding *b,
     150                                          const char *name,
     151                                          const char *value);
     152uint32_t dcerpc_binding_get_flags(const struct dcerpc_binding *b);
     153NTSTATUS dcerpc_binding_set_flags(struct dcerpc_binding *b,
     154                                  uint32_t additional,
     155                                  uint32_t clear);
    130156NTSTATUS dcerpc_floor_get_lhs_data(const struct epm_floor *epm_floor, struct ndr_syntax_id *syntax);
    131157const char *derpc_transport_string_by_transport(enum dcerpc_transport_t t);
     158enum dcerpc_transport_t dcerpc_transport_by_name(const char *name);
    132159enum dcerpc_transport_t dcerpc_transport_by_tower(const struct epm_tower *tower);
    133160
     
    136163void dcerpc_set_frag_length(DATA_BLOB *blob, uint16_t v);
    137164uint16_t dcerpc_get_frag_length(const DATA_BLOB *blob);
    138 uint32_t dcerpc_get_call_id(const DATA_BLOB *blob);
    139165void dcerpc_set_auth_length(DATA_BLOB *blob, uint16_t v);
    140166uint8_t dcerpc_get_endian_flag(DATA_BLOB *blob);
     167const char *dcerpc_default_transport_endpoint(TALLOC_CTX *mem_ctx,
     168                                              enum dcerpc_transport_t transport,
     169                                              const struct ndr_interface_table *table);
    141170
    142171/**
     
    187216                                uint32_t timeout);
    188217
     218        void (*auth_info)(struct dcerpc_binding_handle *h,
     219                          enum dcerpc_AuthType *auth_type,
     220                          enum dcerpc_AuthLevel *auth_level);
     221
    189222        struct tevent_req *(*raw_call_send)(TALLOC_CTX *mem_ctx,
    190223                                            struct tevent_context *ev,
     
    257290                                           uint32_t timeout);
    258291
     292void dcerpc_binding_handle_auth_info(struct dcerpc_binding_handle *h,
     293                                     enum dcerpc_AuthType *auth_type,
     294                                     enum dcerpc_AuthLevel *auth_level);
     295
    259296struct tevent_req *dcerpc_binding_handle_raw_call_send(TALLOC_CTX *mem_ctx,
    260297                                                struct tevent_context *ev,
     
    343380                const struct dcerpc_sec_vt_header2 *header2);
    344381
     382/**
     383 * @brief check and optionally extract the Bind Time Features from
     384 * the given ndr_syntax_id.
     385 *
     386 * <a href="http://msdn.microsoft.com/en-us/library/cc243715.aspx">MS-RPCE 3.3.1.5.3 Bind Time Feature Negotiation</a>.
     387 *
     388 * @param[in]  s the syntax that should be checked.
     389 *
     390 * @param[out] features This is optional, it will be filled with the extracted
     391 *                      features the on success, otherwise it's filled with 0.
     392 *
     393 * @return true if the syntax matches the 6CB71C2C-9812-4540 prefix with version 1, false otherwise.
     394 *
     395 * @see dcerpc_construct_bind_time_features
     396 */
     397bool dcerpc_extract_bind_time_features(struct ndr_syntax_id syntax, uint64_t *features);
     398
     399/**
     400 * @brief Construct a ndr_syntax_id used for Bind Time Features Negotiation.
     401 *
     402 * <a href="http://msdn.microsoft.com/en-us/library/cc243715.aspx">MS-RPCE 3.3.1.5.3 Bind Time Feature Negotiation</a>.
     403 *
     404 * @param[in] features The supported features.
     405 *
     406 * @return The ndr_syntax_id with the given features.
     407 *
     408 * @see dcerpc_extract_bind_time_features
     409 */
     410struct ndr_syntax_id dcerpc_construct_bind_time_features(uint64_t features);
     411
     412#define DCERPC_AUTH_PAD_LENGTH(stub_length) (\
     413        (((stub_length) % DCERPC_AUTH_PAD_ALIGNMENT) > 0)?\
     414        (DCERPC_AUTH_PAD_ALIGNMENT - (stub_length) % DCERPC_AUTH_PAD_ALIGNMENT):\
     415        0)
     416
    345417#endif /* __DEFAULT_LIBRPC_RPCCOMMON_H__ */
Note: See TracChangeset for help on using the changeset viewer.