Ignore:
Timestamp:
Nov 14, 2012, 12:59:34 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to 3.6.0

Location:
vendor/current/source3/rpc_client
Files:
21 added
2 deleted
11 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source3/rpc_client/cli_lsarpc.c

    r414 r740  
    2424
    2525#include "includes.h"
    26 #include "../librpc/gen_ndr/cli_lsa.h"
     26#include "rpc_client/rpc_client.h"
     27#include "../librpc/gen_ndr/ndr_lsa_c.h"
     28#include "rpc_client/cli_lsarpc.h"
     29#include "rpc_client/init_lsa.h"
     30#include "../libcli/security/security.h"
    2731
    2832/** @defgroup lsa LSA - Local Security Architecture
     
    3943 **/
    4044
    41 /** Open a LSA policy handle
    42  *
    43  * @param cli Handle on an initialised SMB connection */
    44 
    45 NTSTATUS rpccli_lsa_open_policy(struct rpc_pipe_client *cli,
     45NTSTATUS dcerpc_lsa_open_policy(struct dcerpc_binding_handle *h,
    4646                                TALLOC_CTX *mem_ctx,
    47                                 bool sec_qos, uint32 des_access,
    48                                 struct policy_handle *pol)
     47                                bool sec_qos,
     48                                uint32_t des_access,
     49                                struct policy_handle *pol,
     50                                NTSTATUS *result)
    4951{
    5052        struct lsa_ObjectAttribute attr;
     
    6567        }
    6668
    67         return rpccli_lsa_OpenPolicy(cli, mem_ctx,
     69        return dcerpc_lsa_OpenPolicy(h,
     70                                     mem_ctx,
    6871                                     &system_name,
    6972                                     &attr,
    7073                                     des_access,
    71                                      pol);
     74                                     pol,
     75                                     result);
    7276}
    7377
    7478/** Open a LSA policy handle
    75   *
    76   * @param cli Handle on an initialised SMB connection
    77   */
    78 
    79 NTSTATUS rpccli_lsa_open_policy2(struct rpc_pipe_client *cli,
    80                                  TALLOC_CTX *mem_ctx, bool sec_qos,
    81                                  uint32 des_access, struct policy_handle *pol)
     79 *
     80 * @param cli Handle on an initialised SMB connection */
     81
     82NTSTATUS rpccli_lsa_open_policy(struct rpc_pipe_client *cli,
     83                                TALLOC_CTX *mem_ctx,
     84                                bool sec_qos, uint32 des_access,
     85                                struct policy_handle *pol)
     86{
     87        NTSTATUS status;
     88        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
     89
     90        status = dcerpc_lsa_open_policy(cli->binding_handle,
     91                                        mem_ctx,
     92                                        sec_qos,
     93                                        des_access,
     94                                        pol,
     95                                        &result);
     96        if (!NT_STATUS_IS_OK(status)) {
     97                return status;
     98        }
     99
     100        return result;
     101}
     102
     103NTSTATUS dcerpc_lsa_open_policy2(struct dcerpc_binding_handle *h,
     104                                 TALLOC_CTX *mem_ctx,
     105                                 const char *srv_name_slash,
     106                                 bool sec_qos,
     107                                 uint32_t des_access,
     108                                 struct policy_handle *pol,
     109                                 NTSTATUS *result)
    82110{
    83111        struct lsa_ObjectAttribute attr;
     
    97125        }
    98126
    99         return rpccli_lsa_OpenPolicy2(cli, mem_ctx,
    100                                       cli->srv_name_slash,
     127        return dcerpc_lsa_OpenPolicy2(h,
     128                                      mem_ctx,
     129                                      srv_name_slash,
    101130                                      &attr,
    102131                                      des_access,
    103                                       pol);
     132                                      pol,
     133                                      result);
     134}
     135
     136/** Open a LSA policy handle
     137  *
     138  * @param cli Handle on an initialised SMB connection
     139  */
     140
     141NTSTATUS rpccli_lsa_open_policy2(struct rpc_pipe_client *cli,
     142                                 TALLOC_CTX *mem_ctx, bool sec_qos,
     143                                 uint32 des_access, struct policy_handle *pol)
     144{
     145        NTSTATUS status;
     146        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
     147
     148        status = dcerpc_lsa_open_policy2(cli->binding_handle,
     149                                         mem_ctx,
     150                                         cli->srv_name_slash,
     151                                         sec_qos,
     152                                         des_access,
     153                                         pol,
     154                                         &result);
     155        if (!NT_STATUS_IS_OK(status)) {
     156                return status;
     157        }
     158
     159        return result;
    104160}
    105161
     
    107163 *
    108164 * internal version withOUT memory allocation of the target arrays.
    109  * this assumes suffciently sized arrays to store domains, names and types. */
    110 
    111 static NTSTATUS rpccli_lsa_lookup_sids_noalloc(struct rpc_pipe_client *cli,
     165 * this assumes sufficiently sized arrays to store domains, names and types. */
     166
     167static NTSTATUS dcerpc_lsa_lookup_sids_noalloc(struct dcerpc_binding_handle *h,
    112168                                               TALLOC_CTX *mem_ctx,
    113169                                               struct policy_handle *pol,
    114170                                               int num_sids,
    115                                                const DOM_SID *sids,
     171                                               const struct dom_sid *sids,
    116172                                               char **domains,
    117173                                               char **names,
    118174                                               enum lsa_SidType *types,
    119                                                bool use_lookupsids3)
    120 {
    121         NTSTATUS result = NT_STATUS_OK;
    122         TALLOC_CTX *tmp_ctx = NULL;
    123         int i;
     175                                               bool use_lookupsids3,
     176                                               NTSTATUS *presult)
     177{
     178        NTSTATUS status = NT_STATUS_OK;
     179        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
    124180        struct lsa_SidArray sid_array;
    125181        struct lsa_RefDomainList *ref_domains = NULL;
    126182        struct lsa_TransNameArray lsa_names;
     183        enum lsa_LookupNamesLevel level = LSA_LOOKUP_NAMES_ALL;
    127184        uint32_t count = 0;
    128         uint16_t level = 1;
     185        int i;
    129186
    130187        ZERO_STRUCT(lsa_names);
    131 
    132         tmp_ctx = talloc_new(mem_ctx);
    133         if (!tmp_ctx) {
    134                 DEBUG(0, ("rpccli_lsa_lookup_sids_noalloc: out of memory!\n"));
    135                 result = NT_STATUS_UNSUCCESSFUL;
    136                 goto done;
    137         }
    138188
    139189        sid_array.num_sids = num_sids;
    140190        sid_array.sids = TALLOC_ARRAY(mem_ctx, struct lsa_SidPtr, num_sids);
    141         if (!sid_array.sids) {
     191        if (sid_array.sids == NULL) {
    142192                return NT_STATUS_NO_MEMORY;
    143193        }
    144194
    145195        for (i = 0; i<num_sids; i++) {
    146                 sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sids[i]);
     196                sid_array.sids[i].sid = dom_sid_dup(mem_ctx, &sids[i]);
    147197                if (!sid_array.sids[i].sid) {
    148198                        return NT_STATUS_NO_MEMORY;
     
    156206                ZERO_STRUCT(lsa_names2);
    157207
    158                 result = rpccli_lsa_LookupSids3(cli, mem_ctx,
     208                status = dcerpc_lsa_LookupSids3(h,
     209                                                mem_ctx,
    159210                                                &sid_array,
    160211                                                &ref_domains,
     
    162213                                                level,
    163214                                                &count,
    164                                                 0,
    165                                                 0);
    166 
    167                 if (!NT_STATUS_IS_ERR(result)) {
    168                         lsa_names.count = lsa_names2.count;
    169                         lsa_names.names = talloc_array(mem_ctx, struct lsa_TranslatedName, lsa_names.count);
    170                         if (!lsa_names.names) {
     215                                                LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES,
     216                                                LSA_CLIENT_REVISION_2,
     217                                                &result);
     218                if (!NT_STATUS_IS_OK(status)) {
     219                        return status;
     220                }
     221
     222                if(!NT_STATUS_IS_ERR(result)) {
     223                        lsa_names.count = lsa_names2.count;
     224                        lsa_names.names = talloc_array(mem_ctx,
     225                                                       struct lsa_TranslatedName,
     226                                                       lsa_names.count);
     227                        if (lsa_names.names == NULL) {
    171228                                return NT_STATUS_NO_MEMORY;
    172229                        }
     
    179236
    180237        } else {
    181                 result = rpccli_lsa_LookupSids(cli, mem_ctx,
     238                status = dcerpc_lsa_LookupSids(h,
     239                                               mem_ctx,
    182240                                               pol,
    183241                                               &sid_array,
     
    185243                                               &lsa_names,
    186244                                               level,
    187                                                &count);
    188         }
    189 
    190         DEBUG(10, ("LSA_LOOKUPSIDS returned '%s', mapped count = %d'\n",
    191                    nt_errstr(result), count));
     245                                               &count,
     246                                               &result);
     247        }
     248
     249        DEBUG(10, ("LSA_LOOKUPSIDS returned status: '%s', result: '%s', "
     250                   "mapped count = %d'\n",
     251                   nt_errstr(status), nt_errstr(result), count));
     252
     253        if (!NT_STATUS_IS_OK(status)) {
     254                return status;
     255        }
    192256
    193257        if (!NT_STATUS_IS_OK(result) &&
     
    195259            !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
    196260        {
    197                 /* An actual error occured */
    198                 goto done;
     261                *presult = result;
     262                return status;
    199263        }
    200264
    201265        /* Return output parameters */
    202 
    203266        if (NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED) ||
    204267            (count == 0))
     
    209272                        (types)[i] = SID_NAME_UNKNOWN;
    210273                }
    211                 result = NT_STATUS_NONE_MAPPED;
    212                 goto done;
     274                *presult = NT_STATUS_NONE_MAPPED;
     275                return status;
    213276        }
    214277
     
    225288
    226289                        if (name) {
    227                                 (names)[i] = talloc_strdup(mem_ctx, name);
     290                                (names)[i] = talloc_strdup(names, name);
    228291                                if ((names)[i] == NULL) {
    229292                                        DEBUG(0, ("cli_lsa_lookup_sids_noalloc(): out of memory\n"));
    230                                         result = NT_STATUS_UNSUCCESSFUL;
    231                                         goto done;
     293                                        *presult = NT_STATUS_UNSUCCESSFUL;
     294                                        return status;
    232295                                }
    233296                        } else {
    234297                                (names)[i] = NULL;
    235298                        }
    236                         domains[i] = talloc_strdup(
    237                                 mem_ctx, dom_name ? dom_name : "");
     299                        domains[i] = talloc_strdup(domains,
     300                                                  dom_name ? dom_name : "");
    238301                        (types)[i] = lsa_names.names[i].sid_type;
    239302                        if (((domains)[i] == NULL)) {
    240303                                DEBUG(0, ("cli_lsa_lookup_sids_noalloc(): out of memory\n"));
    241                                 result = NT_STATUS_UNSUCCESSFUL;
    242                                 goto done;
     304                                *presult = NT_STATUS_UNSUCCESSFUL;
     305                                return status;
    243306                        }
    244307
     
    250313        }
    251314
    252 done:
    253         TALLOC_FREE(tmp_ctx);
    254         return result;
     315        *presult = NT_STATUS_OK;
     316        return status;
    255317}
    256318
     
    267329#define LOOKUP_SIDS_HUNK_SIZE 1000
    268330
    269 static NTSTATUS rpccli_lsa_lookup_sids_generic(struct rpc_pipe_client *cli,
     331static NTSTATUS dcerpc_lsa_lookup_sids_generic(struct dcerpc_binding_handle *h,
    270332                                               TALLOC_CTX *mem_ctx,
    271333                                               struct policy_handle *pol,
    272334                                               int num_sids,
    273                                                const DOM_SID *sids,
     335                                               const struct dom_sid *sids,
    274336                                               char ***pdomains,
    275337                                               char ***pnames,
    276338                                               enum lsa_SidType **ptypes,
    277                                                bool use_lookupsids3)
    278 {
     339                                               bool use_lookupsids3,
     340                                               NTSTATUS *presult)
     341{
     342        NTSTATUS status = NT_STATUS_OK;
    279343        NTSTATUS result = NT_STATUS_OK;
    280344        int sids_left = 0;
    281345        int sids_processed = 0;
    282         const DOM_SID *hunk_sids = sids;
     346        const struct dom_sid *hunk_sids = sids;
    283347        char **hunk_domains;
    284348        char **hunk_names;
     
    287351        char **names = NULL;
    288352        enum lsa_SidType *types = NULL;
     353        bool have_mapped = false;
     354        bool have_unmapped = false;
    289355
    290356        if (num_sids) {
    291357                if (!(domains = TALLOC_ARRAY(mem_ctx, char *, num_sids))) {
    292358                        DEBUG(0, ("rpccli_lsa_lookup_sids(): out of memory\n"));
    293                         result = NT_STATUS_NO_MEMORY;
     359                        status = NT_STATUS_NO_MEMORY;
    294360                        goto fail;
    295361                }
     
    297363                if (!(names = TALLOC_ARRAY(mem_ctx, char *, num_sids))) {
    298364                        DEBUG(0, ("rpccli_lsa_lookup_sids(): out of memory\n"));
    299                         result = NT_STATUS_NO_MEMORY;
     365                        status = NT_STATUS_NO_MEMORY;
    300366                        goto fail;
    301367                }
     
    303369                if (!(types = TALLOC_ARRAY(mem_ctx, enum lsa_SidType, num_sids))) {
    304370                        DEBUG(0, ("rpccli_lsa_lookup_sids(): out of memory\n"));
    305                         result = NT_STATUS_NO_MEMORY;
     371                        status = NT_STATUS_NO_MEMORY;
    306372                        goto fail;
    307373                }
     
    315381        while (sids_left > 0) {
    316382                int hunk_num_sids;
    317                 NTSTATUS hunk_result = NT_STATUS_OK;
     383                NTSTATUS hunk_result = NT_STATUS_UNSUCCESSFUL;
    318384
    319385                hunk_num_sids = ((sids_left > LOOKUP_SIDS_HUNK_SIZE)
     
    327393                           num_sids));
    328394
    329                 hunk_result = rpccli_lsa_lookup_sids_noalloc(cli,
    330                                                              mem_ctx,
    331                                                              pol,
    332                                                              hunk_num_sids,
    333                                                              hunk_sids,
    334                                                              hunk_domains,
    335                                                              hunk_names,
    336                                                              hunk_types,
    337                                                              use_lookupsids3);
     395                status = dcerpc_lsa_lookup_sids_noalloc(h,
     396                                                        mem_ctx,
     397                                                        pol,
     398                                                        hunk_num_sids,
     399                                                        hunk_sids,
     400                                                        hunk_domains,
     401                                                        hunk_names,
     402                                                        hunk_types,
     403                                                        use_lookupsids3,
     404                                                        &hunk_result);
     405                if (!NT_STATUS_IS_OK(status)) {
     406                        goto fail;
     407                }
    338408
    339409                if (!NT_STATUS_IS_OK(hunk_result) &&
     
    342412                {
    343413                        /* An actual error occured */
    344                         result = hunk_result;
     414                        *presult = hunk_result;
    345415                        goto fail;
    346416                }
    347417
    348                 /* adapt overall result */
    349                 if (( NT_STATUS_IS_OK(result) &&
    350                      !NT_STATUS_IS_OK(hunk_result))
    351                     ||
    352                     ( NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED) &&
    353                      !NT_STATUS_EQUAL(hunk_result, NT_STATUS_NONE_MAPPED)))
    354                 {
    355                         result = STATUS_SOME_UNMAPPED;
     418                if (NT_STATUS_IS_OK(hunk_result)) {
     419                        have_mapped = true;
     420                }
     421                if (NT_STATUS_EQUAL(hunk_result, NT_STATUS_NONE_MAPPED)) {
     422                        have_unmapped = true;
     423                }
     424                if (NT_STATUS_EQUAL(hunk_result, STATUS_SOME_UNMAPPED)) {
     425                        int i;
     426                        for (i=0; i<hunk_num_sids; i++) {
     427                                if (hunk_types[i] == SID_NAME_UNKNOWN) {
     428                                        have_unmapped = true;
     429                                } else {
     430                                        have_mapped = true;
     431                                }
     432                        }
    356433                }
    357434
     
    367444        *pnames = names;
    368445        *ptypes = types;
    369         return result;
     446
     447        if (!have_mapped) {
     448                result = NT_STATUS_NONE_MAPPED;
     449        }
     450        if (have_unmapped) {
     451                result = STATUS_SOME_UNMAPPED;
     452        }
     453        *presult = result;
     454
     455        return status;
    370456
    371457fail:
     
    373459        TALLOC_FREE(names);
    374460        TALLOC_FREE(types);
    375         return result;
     461
     462        return status;
     463}
     464
     465NTSTATUS dcerpc_lsa_lookup_sids(struct dcerpc_binding_handle *h,
     466                                TALLOC_CTX *mem_ctx,
     467                                struct policy_handle *pol,
     468                                int num_sids,
     469                                const struct dom_sid *sids,
     470                                char ***pdomains,
     471                                char ***pnames,
     472                                enum lsa_SidType **ptypes,
     473                                NTSTATUS *result)
     474{
     475        return dcerpc_lsa_lookup_sids_generic(h,
     476                                              mem_ctx,
     477                                              pol,
     478                                              num_sids,
     479                                              sids,
     480                                              pdomains,
     481                                              pnames,
     482                                              ptypes,
     483                                              false,
     484                                              result);
    376485}
    377486
     
    380489                                struct policy_handle *pol,
    381490                                int num_sids,
    382                                 const DOM_SID *sids,
     491                                const struct dom_sid *sids,
    383492                                char ***pdomains,
    384493                                char ***pnames,
    385494                                enum lsa_SidType **ptypes)
    386495{
    387         return rpccli_lsa_lookup_sids_generic(cli, mem_ctx, pol, num_sids, sids,
    388                                               pdomains, pnames, ptypes, false);
     496        NTSTATUS status;
     497        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
     498
     499        status = dcerpc_lsa_lookup_sids_generic(cli->binding_handle,
     500                                                mem_ctx,
     501                                                pol,
     502                                                num_sids,
     503                                                sids,
     504                                                pdomains,
     505                                                pnames,
     506                                                ptypes,
     507                                                false,
     508                                                &result);
     509        if (!NT_STATUS_IS_OK(status)) {
     510                return status;
     511        }
     512
     513        return result;
     514}
     515
     516NTSTATUS dcerpc_lsa_lookup_sids3(struct dcerpc_binding_handle *h,
     517                                 TALLOC_CTX *mem_ctx,
     518                                 struct policy_handle *pol,
     519                                 int num_sids,
     520                                 const struct dom_sid *sids,
     521                                 char ***pdomains,
     522                                 char ***pnames,
     523                                 enum lsa_SidType **ptypes,
     524                                 NTSTATUS *result)
     525{
     526        return dcerpc_lsa_lookup_sids_generic(h,
     527                                              mem_ctx,
     528                                              pol,
     529                                              num_sids,
     530                                              sids,
     531                                              pdomains,
     532                                              pnames,
     533                                              ptypes,
     534                                              true,
     535                                              result);
    389536}
    390537
     
    393540                                 struct policy_handle *pol,
    394541                                 int num_sids,
    395                                  const DOM_SID *sids,
     542                                 const struct dom_sid *sids,
    396543                                 char ***pdomains,
    397544                                 char ***pnames,
    398545                                 enum lsa_SidType **ptypes)
    399546{
    400         return rpccli_lsa_lookup_sids_generic(cli, mem_ctx, pol, num_sids, sids,
    401                                               pdomains, pnames, ptypes, true);
     547        NTSTATUS status;
     548        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
     549
     550        status = dcerpc_lsa_lookup_sids_generic(cli->binding_handle,
     551                                                mem_ctx,
     552                                                pol,
     553                                                num_sids,
     554                                                sids,
     555                                                pdomains,
     556                                                pnames,
     557                                                ptypes,
     558                                                true,
     559                                                &result);
     560        if (!NT_STATUS_IS_OK(status)) {
     561                return status;
     562        }
     563
     564        return result;
    402565}
    403566
    404567/** Lookup a list of names */
    405568
    406 static NTSTATUS rpccli_lsa_lookup_names_generic(struct rpc_pipe_client *cli,
     569static NTSTATUS dcerpc_lsa_lookup_names_generic(struct dcerpc_binding_handle *h,
    407570                                                TALLOC_CTX *mem_ctx,
    408                                                 struct policy_handle *pol, int num_names,
     571                                                struct policy_handle *pol,
     572                                                uint32_t num_names,
    409573                                                const char **names,
    410574                                                const char ***dom_names,
    411                                                 int level,
    412                                                 DOM_SID **sids,
     575                                                enum lsa_LookupNamesLevel level,
     576                                                struct dom_sid **sids,
    413577                                                enum lsa_SidType **types,
    414                                                 bool use_lookupnames4)
    415 {
    416         NTSTATUS result;
    417         int i;
     578                                                bool use_lookupnames4,
     579                                                NTSTATUS *presult)
     580{
     581        NTSTATUS status;
    418582        struct lsa_String *lsa_names = NULL;
    419583        struct lsa_RefDomainList *domains = NULL;
     
    421585        struct lsa_TransSidArray3 sid_array3;
    422586        uint32_t count = 0;
     587        uint32_t i;
    423588
    424589        ZERO_STRUCT(sid_array);
     
    426591
    427592        lsa_names = TALLOC_ARRAY(mem_ctx, struct lsa_String, num_names);
    428         if (!lsa_names) {
     593        if (lsa_names == NULL) {
    429594                return NT_STATUS_NO_MEMORY;
    430595        }
    431596
    432         for (i=0; i<num_names; i++) {
     597        for (i = 0; i < num_names; i++) {
    433598                init_lsa_String(&lsa_names[i], names[i]);
    434599        }
    435600
    436601        if (use_lookupnames4) {
    437                 result = rpccli_lsa_LookupNames4(cli, mem_ctx,
     602                status = dcerpc_lsa_LookupNames4(h,
     603                                                 mem_ctx,
    438604                                                 num_names,
    439605                                                 lsa_names,
     
    442608                                                 level,
    443609                                                 &count,
    444                                                  0,
    445                                                  0);
     610                                                 LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES,
     611                                                 LSA_CLIENT_REVISION_2,
     612                                                 presult);
    446613        } else {
    447                 result = rpccli_lsa_LookupNames(cli, mem_ctx,
    448                                                 pol,
     614                status = dcerpc_lsa_LookupNames(h,
     615                                                mem_ctx,
     616                                                pol,
    449617                                                num_names,
    450618                                                lsa_names,
     
    452620                                                &sid_array,
    453621                                                level,
    454                                                 &count);
    455         }
    456 
    457         if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) !=
    458             NT_STATUS_V(STATUS_SOME_UNMAPPED)) {
    459 
     622                                                &count,
     623                                                presult);
     624        }
     625        if (!NT_STATUS_IS_OK(status)) {
     626                goto done;
     627        }
     628
     629        if (!NT_STATUS_IS_OK(*presult) &&
     630            !NT_STATUS_EQUAL(*presult, STATUS_SOME_UNMAPPED)) {
    460631                /* An actual error occured */
    461 
    462632                goto done;
    463633        }
    464634
    465635        /* Return output parameters */
    466 
    467636        if (count == 0) {
    468                 result = NT_STATUS_NONE_MAPPED;
     637                *presult = NT_STATUS_NONE_MAPPED;
    469638                goto done;
    470639        }
    471640
    472641        if (num_names) {
    473                 if (!((*sids = TALLOC_ARRAY(mem_ctx, DOM_SID, num_names)))) {
     642                if (!((*sids = TALLOC_ARRAY(mem_ctx, struct dom_sid, num_names)))) {
    474643                        DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
    475                         result = NT_STATUS_NO_MEMORY;
     644                        *presult = NT_STATUS_NO_MEMORY;
    476645                        goto done;
    477646                }
     
    479648                if (!((*types = TALLOC_ARRAY(mem_ctx, enum lsa_SidType, num_names)))) {
    480649                        DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
    481                         result = NT_STATUS_NO_MEMORY;
     650                        *presult = NT_STATUS_NO_MEMORY;
    482651                        goto done;
    483652                }
     
    487656                        if (*dom_names == NULL) {
    488657                                DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
    489                                 result = NT_STATUS_NO_MEMORY;
     658                                *presult = NT_STATUS_NO_MEMORY;
    490659                                goto done;
    491660                        }
     
    501670        for (i = 0; i < num_names; i++) {
    502671                uint32_t dom_idx;
    503                 DOM_SID *sid = &(*sids)[i];
     672                struct dom_sid *sid = &(*sids)[i];
    504673
    505674                if (use_lookupnames4) {
     
    538707
    539708 done:
    540 
    541         return result;
     709        return status;
     710}
     711
     712NTSTATUS dcerpc_lsa_lookup_names(struct dcerpc_binding_handle *h,
     713                                 TALLOC_CTX *mem_ctx,
     714                                 struct policy_handle *pol,
     715                                 uint32_t num_names,
     716                                 const char **names,
     717                                 const char ***dom_names,
     718                                 enum lsa_LookupNamesLevel level,
     719                                 struct dom_sid **sids,
     720                                 enum lsa_SidType **types,
     721                                 NTSTATUS *result)
     722{
     723        return dcerpc_lsa_lookup_names_generic(h,
     724                                               mem_ctx,
     725                                               pol,
     726                                               num_names,
     727                                               names,
     728                                               dom_names,
     729                                               level,
     730                                               sids,
     731                                               types,
     732                                               false,
     733                                               result);
    542734}
    543735
    544736NTSTATUS rpccli_lsa_lookup_names(struct rpc_pipe_client *cli,
    545737                                 TALLOC_CTX *mem_ctx,
    546                                  struct policy_handle *pol, int num_names,
     738                                 struct policy_handle *pol,
     739                                 int num_names,
    547740                                 const char **names,
    548741                                 const char ***dom_names,
    549742                                 int level,
    550                                  DOM_SID **sids,
     743                                 struct dom_sid **sids,
    551744                                 enum lsa_SidType **types)
    552745{
    553         return rpccli_lsa_lookup_names_generic(cli, mem_ctx, pol, num_names,
    554                                                names, dom_names, level, sids,
    555                                                types, false);
     746        NTSTATUS status;
     747        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
     748
     749        status = dcerpc_lsa_lookup_names(cli->binding_handle,
     750                                         mem_ctx,
     751                                         pol,
     752                                         num_names,
     753                                         names,
     754                                         dom_names,
     755                                         level,
     756                                         sids,
     757                                         types,
     758                                         &result);
     759        if (!NT_STATUS_IS_OK(status)) {
     760                return status;
     761        }
     762
     763        return result;
     764}
     765
     766NTSTATUS dcerpc_lsa_lookup_names4(struct dcerpc_binding_handle *h,
     767                                  TALLOC_CTX *mem_ctx,
     768                                  struct policy_handle *pol,
     769                                  uint32_t num_names,
     770                                  const char **names,
     771                                  const char ***dom_names,
     772                                  enum lsa_LookupNamesLevel level,
     773                                  struct dom_sid **sids,
     774                                  enum lsa_SidType **types,
     775                                  NTSTATUS *result)
     776{
     777        return dcerpc_lsa_lookup_names_generic(h,
     778                                               mem_ctx,
     779                                               pol,
     780                                               num_names,
     781                                               names,
     782                                               dom_names,
     783                                               level,
     784                                               sids,
     785                                               types,
     786                                               true,
     787                                               result);
    556788}
    557789
    558790NTSTATUS rpccli_lsa_lookup_names4(struct rpc_pipe_client *cli,
    559791                                  TALLOC_CTX *mem_ctx,
    560                                   struct policy_handle *pol, int num_names,
     792                                  struct policy_handle *pol,
     793                                  int num_names,
    561794                                  const char **names,
    562795                                  const char ***dom_names,
    563796                                  int level,
    564                                   DOM_SID **sids,
     797                                  struct dom_sid **sids,
    565798                                  enum lsa_SidType **types)
    566799{
    567         return rpccli_lsa_lookup_names_generic(cli, mem_ctx, pol, num_names,
    568                                                names, dom_names, level, sids,
    569                                                types, true);
    570 }
     800        NTSTATUS status;
     801        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
     802
     803        status = dcerpc_lsa_lookup_names4(cli->binding_handle,
     804                                          mem_ctx,
     805                                          pol,
     806                                          num_names,
     807                                          names,
     808                                          dom_names,
     809                                          level,
     810                                          sids,
     811                                          types,
     812                                          &result);
     813        if (!NT_STATUS_IS_OK(status)) {
     814                return status;
     815        }
     816
     817        return result;
     818}
  • vendor/current/source3/rpc_client/cli_netlogon.c

    r594 r740  
    2222
    2323#include "includes.h"
     24#include "rpc_client/rpc_client.h"
    2425#include "../libcli/auth/libcli_auth.h"
    25 #include "../librpc/gen_ndr/cli_netlogon.h"
     26#include "../librpc/gen_ndr/ndr_netlogon_c.h"
     27#include "rpc_client/cli_netlogon.h"
     28#include "rpc_client/init_netlogon.h"
     29#include "rpc_client/util_netlogon.h"
     30#include "../libcli/security/security.h"
    2631
    2732/****************************************************************************
     
    4045                                     uint32_t *neg_flags_inout)
    4146{
     47        NTSTATUS status;
    4248        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
    4349        struct netr_Credential clnt_chal_send;
     
    4753        fstring mach_acct;
    4854        uint32_t neg_flags = *neg_flags_inout;
     55        struct dcerpc_binding_handle *b = cli->binding_handle;
    4956
    5057        if (!ndr_syntax_id_equal(&cli->abstract_syntax,
     
    6572
    6673        /* Get the server challenge. */
    67         result = rpccli_netr_ServerReqChallenge(cli, talloc_tos(),
     74        status = dcerpc_netr_ServerReqChallenge(b, talloc_tos(),
    6875                                                cli->srv_name_slash,
    6976                                                clnt_name,
    7077                                                &clnt_chal_send,
    71                                                 &srv_chal_recv);
     78                                                &srv_chal_recv,
     79                                                &result);
     80        if (!NT_STATUS_IS_OK(status)) {
     81                return status;
     82        }
    7283        if (!NT_STATUS_IS_OK(result)) {
    7384                return result;
     
    7586
    7687        /* Calculate the session key and client credentials */
    77        
     88
    7889        cli->dc = netlogon_creds_client_init(cli,
    7990                                    mach_acct,
     
    93104         */
    94105
    95         result = rpccli_netr_ServerAuthenticate2(cli, talloc_tos(),
     106        status = dcerpc_netr_ServerAuthenticate2(b, talloc_tos(),
    96107                                                 cli->srv_name_slash,
    97108                                                 cli->dc->account_name,
     
    100111                                                 &clnt_chal_send, /* input. */
    101112                                                 &srv_chal_recv, /* output. */
    102                                                  &neg_flags);
    103 
     113                                                 &neg_flags,
     114                                                 &result);
     115        if (!NT_STATUS_IS_OK(status)) {
     116                return status;
     117        }
    104118        /* we might be talking to NT4, so let's downgrade in that case and retry
    105119         * with the returned neg_flags - gd */
     
    149163                                   const char *password,
    150164                                   const char *workstation,
     165                                   uint16_t validation_level,
    151166                                   int logon_type)
    152167{
    153168        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
     169        NTSTATUS status;
    154170        struct netr_Authenticator clnt_creds;
    155171        struct netr_Authenticator ret_creds;
     
    157173        union netr_Validation validation;
    158174        uint8_t authoritative;
    159         int validation_level = 3;
    160175        fstring clnt_name_slash;
    161         uint8 zeros[16];
     176        struct dcerpc_binding_handle *b = cli->binding_handle;
    162177
    163178        ZERO_STRUCT(ret_creds);
    164         ZERO_STRUCT(zeros);
    165179
    166180        logon = TALLOC_ZERO_P(mem_ctx, union netr_LogonLevel);
     
    264278        }
    265279
    266         result = rpccli_netr_LogonSamLogon(cli, mem_ctx,
     280        status = dcerpc_netr_LogonSamLogon(b, mem_ctx,
    267281                                           cli->srv_name_slash,
    268282                                           global_myname(),
     
    273287                                           validation_level,
    274288                                           &validation,
    275                                            &authoritative);
     289                                           &authoritative,
     290                                           &result);
     291        if (!NT_STATUS_IS_OK(status)) {
     292                return status;
     293        }
    276294
    277295        /* Always check returned credentials */
     
    282300
    283301        return result;
    284 }
    285 
    286 #define COPY_LSA_STRING(mem_ctx, in, out, name) do { \
    287         if (in->name.string) { \
    288                 out->name.string = talloc_strdup(mem_ctx, in->name.string); \
    289                 NT_STATUS_HAVE_NO_MEMORY(out->name.string); \
    290         } \
    291 } while (0)
    292 
    293 static NTSTATUS copy_netr_SamBaseInfo(TALLOC_CTX *mem_ctx,
    294                                       const struct netr_SamBaseInfo *in,
    295                                       struct netr_SamBaseInfo *out)
    296 {
    297         /* first copy all, then realloc pointers */
    298         *out = *in;
    299 
    300         COPY_LSA_STRING(mem_ctx, in, out, account_name);
    301         COPY_LSA_STRING(mem_ctx, in, out, full_name);
    302         COPY_LSA_STRING(mem_ctx, in, out, logon_script);
    303         COPY_LSA_STRING(mem_ctx, in, out, profile_path);
    304         COPY_LSA_STRING(mem_ctx, in, out, home_directory);
    305         COPY_LSA_STRING(mem_ctx, in, out, home_drive);
    306 
    307         if (in->groups.count) {
    308                 out->groups.rids = (struct samr_RidWithAttribute *)
    309                         talloc_memdup(mem_ctx, in->groups.rids,
    310                                 (sizeof(struct samr_RidWithAttribute) *
    311                                         in->groups.count));
    312                 NT_STATUS_HAVE_NO_MEMORY(out->groups.rids);
    313         }
    314 
    315         COPY_LSA_STRING(mem_ctx, in, out, logon_server);
    316         COPY_LSA_STRING(mem_ctx, in, out, domain);
    317 
    318         if (in->domain_sid) {
    319                 out->domain_sid = sid_dup_talloc(mem_ctx, in->domain_sid);
    320                 NT_STATUS_HAVE_NO_MEMORY(out->domain_sid);
    321         }
    322 
    323         return NT_STATUS_OK;
    324302}
    325303
     
    391369{
    392370        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
     371        NTSTATUS status;
    393372        const char *workstation_name_slash;
    394373        const char *server_name_slash;
    395         uint8 zeros[16];
    396374        struct netr_Authenticator clnt_creds;
    397375        struct netr_Authenticator ret_creds;
     
    402380        struct netr_ChallengeResponse lm;
    403381        struct netr_ChallengeResponse nt;
     382        struct dcerpc_binding_handle *b = cli->binding_handle;
    404383
    405384        *info3 = NULL;
    406385
    407         ZERO_STRUCT(zeros);
    408386        ZERO_STRUCT(ret_creds);
    409387
     
    462440        /* Marshall data and send request */
    463441
    464         result = rpccli_netr_LogonSamLogon(cli, mem_ctx,
     442        status = dcerpc_netr_LogonSamLogon(b, mem_ctx,
    465443                                           server_name_slash,
    466444                                           global_myname(),
     
    471449                                           validation_level,
    472450                                           &validation,
    473                                            &authoritative);
    474         if (!NT_STATUS_IS_OK(result)) {
    475                 return result;
     451                                           &authoritative,
     452                                           &result);
     453        if (!NT_STATUS_IS_OK(status)) {
     454                return status;
    476455        }
    477456
     
    480459                DEBUG(0,("rpccli_netlogon_sam_network_logon: credentials chain check failed\n"));
    481460                return NT_STATUS_ACCESS_DENIED;
     461        }
     462
     463        if (!NT_STATUS_IS_OK(result)) {
     464                return result;
    482465        }
    483466
     
    506489{
    507490        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
     491        NTSTATUS status;
    508492        const char *workstation_name_slash;
    509493        const char *server_name_slash;
    510         uint8 zeros[16];
    511494        union netr_LogonLevel *logon = NULL;
    512495        struct netr_NetworkInfo *network_info;
     
    516499        struct netr_ChallengeResponse nt;
    517500        uint32_t flags = 0;
     501        struct dcerpc_binding_handle *b = cli->binding_handle;
    518502
    519503        *info3 = NULL;
    520 
    521         ZERO_STRUCT(zeros);
    522504
    523505        ZERO_STRUCT(lm);
     
    573555        /* Marshall data and send request */
    574556
    575         result = rpccli_netr_LogonSamLogonEx(cli, mem_ctx,
     557        status = dcerpc_netr_LogonSamLogonEx(b, mem_ctx,
    576558                                             server_name_slash,
    577559                                             global_myname(),
     
    581563                                             &validation,
    582564                                             &authoritative,
    583                                              &flags);
     565                                             &flags,
     566                                             &result);
     567        if (!NT_STATUS_IS_OK(status)) {
     568                return status;
     569        }
     570
    584571        if (!NT_STATUS_IS_OK(result)) {
    585572                return result;
     
    613600                                            enum netr_SchannelType sec_channel_type)
    614601{
    615         NTSTATUS result;
     602        NTSTATUS result, status;
    616603        struct netr_Authenticator clnt_creds, srv_cred;
     604        struct dcerpc_binding_handle *b = cli->binding_handle;
    617605
    618606        if (!cli->dc) {
     
    643631                                        &new_password);
    644632
    645                 result = rpccli_netr_ServerPasswordSet2(cli, mem_ctx,
     633                status = dcerpc_netr_ServerPasswordSet2(b, mem_ctx,
    646634                                                        cli->srv_name_slash,
    647635                                                        cli->dc->account_name,
     
    650638                                                        &clnt_creds,
    651639                                                        &srv_cred,
    652                                                         &new_password);
    653                 if (!NT_STATUS_IS_OK(result)) {
    654                         DEBUG(0,("rpccli_netr_ServerPasswordSet2 failed: %s\n",
    655                                 nt_errstr(result)));
    656                         return result;
     640                                                        &new_password,
     641                                                        &result);
     642                if (!NT_STATUS_IS_OK(status)) {
     643                        DEBUG(0,("dcerpc_netr_ServerPasswordSet2 failed: %s\n",
     644                                nt_errstr(status)));
     645                        return status;
    657646                }
    658647        } else {
     
    662651                netlogon_creds_des_encrypt(cli->dc, &new_password);
    663652
    664                 result = rpccli_netr_ServerPasswordSet(cli, mem_ctx,
     653                status = dcerpc_netr_ServerPasswordSet(b, mem_ctx,
    665654                                                       cli->srv_name_slash,
    666655                                                       cli->dc->account_name,
     
    669658                                                       &clnt_creds,
    670659                                                       &srv_cred,
    671                                                        &new_password);
    672                 if (!NT_STATUS_IS_OK(result)) {
    673                         DEBUG(0,("rpccli_netr_ServerPasswordSet failed: %s\n",
    674                                 nt_errstr(result)));
    675                         return result;
     660                                                       &new_password,
     661                                                       &result);
     662                if (!NT_STATUS_IS_OK(status)) {
     663                        DEBUG(0,("dcerpc_netr_ServerPasswordSet failed: %s\n",
     664                                nt_errstr(status)));
     665                        return status;
    676666                }
    677667        }
     
    683673        }
    684674
     675        if (!NT_STATUS_IS_OK(result)) {
     676                DEBUG(0,("dcerpc_netr_ServerPasswordSet{2} failed: %s\n",
     677                        nt_errstr(result)));
     678                return result;
     679        }
     680
    685681        return result;
    686682}
  • vendor/current/source3/rpc_client/cli_pipe.c

    r597 r740  
    1 /* 
     1/*
    22 *  Unix SMB/CIFS implementation.
    3  *  RPC Pipe client / server routines
     3 *  RPC Pipe client routines
    44 *  Largely rewritten by Jeremy Allison             2005.
    5  * 
     5 *  Heavily modified by Simo Sorce                  2010.
     6 *
    67 *  This program is free software; you can redistribute it and/or modify
    78 *  it under the terms of the GNU General Public License as published by
    89 *  the Free Software Foundation; either version 3 of the License, or
    910 *  (at your option) any later version.
    10  * 
     11 *
    1112 *  This program is distributed in the hope that it will be useful,
    1213 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    1314 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1415 *  GNU General Public License for more details.
    15  * 
     16 *
    1617 *  You should have received a copy of the GNU General Public License
    1718 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
     
    1920
    2021#include "includes.h"
    21 #include "librpc/gen_ndr/cli_epmapper.h"
     22#include "../lib/util/tevent_ntstatus.h"
     23#include "librpc/gen_ndr/ndr_epmapper_c.h"
    2224#include "../librpc/gen_ndr/ndr_schannel.h"
     25#include "../librpc/gen_ndr/ndr_dssetup.h"
    2326#include "../libcli/auth/schannel.h"
    2427#include "../libcli/auth/spnego.h"
    25 #include "smb_krb5.h"
     28#include "../libcli/auth/ntlmssp.h"
     29#include "ntlmssp_wrap.h"
     30#include "librpc/gen_ndr/ndr_dcerpc.h"
     31#include "librpc/rpc/dcerpc.h"
     32#include "librpc/crypto/gse.h"
     33#include "librpc/crypto/spnego.h"
     34#include "rpc_dce.h"
     35#include "cli_pipe.h"
     36#include "client.h"
    2637
    2738#undef DBGC_CLASS
    2839#define DBGC_CLASS DBGC_RPC_CLI
    29 
    30 static const char *get_pipe_name_from_iface(
    31         TALLOC_CTX *mem_ctx, const struct ndr_interface_table *interface)
    32 {
    33         int i;
    34         const struct ndr_interface_string_array *ep = interface->endpoints;
    35         char *p;
    36 
    37         for (i=0; i<ep->count; i++) {
    38                 if (strncmp(ep->names[i], "ncacn_np:[\\pipe\\", 16) == 0) {
    39                         break;
    40                 }
    41         }
    42         if (i == ep->count) {
    43                 return NULL;
    44         }
    45 
    46         /*
    47          * extract the pipe name without \\pipe from for example
    48          * ncacn_np:[\\pipe\\epmapper]
    49          */
    50         p = strchr(ep->names[i]+15, ']');
    51         if (p == NULL) {
    52                 return "PIPE";
    53         }
    54         return talloc_strndup(mem_ctx, ep->names[i]+15, p - ep->names[i] - 15);
    55 }
    56 
    57 static const struct ndr_interface_table **interfaces;
    58 
    59 bool smb_register_ndr_interface(const struct ndr_interface_table *interface)
    60 {
    61         int num_interfaces = talloc_array_length(interfaces);
    62         const struct ndr_interface_table **tmp;
    63         int i;
    64 
    65         for (i=0; i<num_interfaces; i++) {
    66                 if (ndr_syntax_id_equal(&interfaces[i]->syntax_id,
    67                                         &interface->syntax_id)) {
    68                         return true;
    69                 }
    70         }
    71 
    72         tmp = talloc_realloc(NULL, interfaces,
    73                              const struct ndr_interface_table *,
    74                              num_interfaces + 1);
    75         if (tmp == NULL) {
    76                 DEBUG(1, ("smb_register_ndr_interface: talloc failed\n"));
    77                 return false;
    78         }
    79         interfaces = tmp;
    80         interfaces[num_interfaces] = interface;
    81         return true;
    82 }
    83 
    84 static bool initialize_interfaces(void)
    85 {
    86         if (!smb_register_ndr_interface(&ndr_table_lsarpc)) {
    87                 return false;
    88         }
    89         if (!smb_register_ndr_interface(&ndr_table_dssetup)) {
    90                 return false;
    91         }
    92         if (!smb_register_ndr_interface(&ndr_table_samr)) {
    93                 return false;
    94         }
    95         if (!smb_register_ndr_interface(&ndr_table_netlogon)) {
    96                 return false;
    97         }
    98         if (!smb_register_ndr_interface(&ndr_table_srvsvc)) {
    99                 return false;
    100         }
    101         if (!smb_register_ndr_interface(&ndr_table_wkssvc)) {
    102                 return false;
    103         }
    104         if (!smb_register_ndr_interface(&ndr_table_winreg)) {
    105                 return false;
    106         }
    107         if (!smb_register_ndr_interface(&ndr_table_spoolss)) {
    108                 return false;
    109         }
    110         if (!smb_register_ndr_interface(&ndr_table_netdfs)) {
    111                 return false;
    112         }
    113         if (!smb_register_ndr_interface(&ndr_table_rpcecho)) {
    114                 return false;
    115         }
    116         if (!smb_register_ndr_interface(&ndr_table_initshutdown)) {
    117                 return false;
    118         }
    119         if (!smb_register_ndr_interface(&ndr_table_svcctl)) {
    120                 return false;
    121         }
    122         if (!smb_register_ndr_interface(&ndr_table_eventlog)) {
    123                 return false;
    124         }
    125         if (!smb_register_ndr_interface(&ndr_table_ntsvcs)) {
    126                 return false;
    127         }
    128         if (!smb_register_ndr_interface(&ndr_table_epmapper)) {
    129                 return false;
    130         }
    131         if (!smb_register_ndr_interface(&ndr_table_drsuapi)) {
    132                 return false;
    133         }
    134         return true;
    135 }
    136 
    137 const struct ndr_interface_table *get_iface_from_syntax(
    138         const struct ndr_syntax_id *syntax)
    139 {
    140         int num_interfaces;
    141         int i;
    142 
    143         if (interfaces == NULL) {
    144                 if (!initialize_interfaces()) {
    145                         return NULL;
    146                 }
    147         }
    148         num_interfaces = talloc_array_length(interfaces);
    149 
    150         for (i=0; i<num_interfaces; i++) {
    151                 if (ndr_syntax_id_equal(&interfaces[i]->syntax_id, syntax)) {
    152                         return interfaces[i];
    153                 }
    154         }
    155 
    156         return NULL;
    157 }
    158 
    159 /****************************************************************************
    160  Return the pipe name from the interface.
    161  ****************************************************************************/
    162 
    163 const char *get_pipe_name_from_syntax(TALLOC_CTX *mem_ctx,
    164                                       const struct ndr_syntax_id *syntax)
    165 {
    166         const struct ndr_interface_table *interface;
    167         char *guid_str;
    168         const char *result;
    169 
    170         interface = get_iface_from_syntax(syntax);
    171         if (interface != NULL) {
    172                 result = get_pipe_name_from_iface(mem_ctx, interface);
    173                 if (result != NULL) {
    174                         return result;
    175                 }
    176         }
    177 
    178         /*
    179          * Here we should ask \\epmapper, but for now our code is only
    180          * interested in the known pipes mentioned in pipe_names[]
    181          */
    182 
    183         guid_str = GUID_string(talloc_tos(), &syntax->uuid);
    184         if (guid_str == NULL) {
    185                 return NULL;
    186         }
    187         result = talloc_asprintf(mem_ctx, "Interface %s.%d", guid_str,
    188                                  (int)syntax->if_version);
    189         TALLOC_FREE(guid_str);
    190 
    191         if (result == NULL) {
    192                 return "PIPE";
    193         }
    194         return result;
    195 }
    196 
    197 /********************************************************************
    198  Map internal value to wire value.
    199  ********************************************************************/
    200 
    201 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
    202 {
    203         switch (auth_type) {
    204 
    205         case PIPE_AUTH_TYPE_NONE:
    206                 return DCERPC_AUTH_TYPE_NONE;
    207 
    208         case PIPE_AUTH_TYPE_NTLMSSP:
    209                 return DCERPC_AUTH_TYPE_NTLMSSP;
    210 
    211         case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
    212         case PIPE_AUTH_TYPE_SPNEGO_KRB5:
    213                 return DCERPC_AUTH_TYPE_SPNEGO;
    214 
    215         case PIPE_AUTH_TYPE_SCHANNEL:
    216                 return DCERPC_AUTH_TYPE_SCHANNEL;
    217 
    218         case PIPE_AUTH_TYPE_KRB5:
    219                 return DCERPC_AUTH_TYPE_KRB5;
    220 
    221         default:
    222                 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
    223                         "auth type %u\n",
    224                         (unsigned int)auth_type ));
    225                 break;
    226         }
    227         return -1;
    228 }
    22940
    23041/********************************************************************
     
    25061        return ++call_id;
    25162}
    252 
    253 /*
    254  * Realloc pdu to have a least "size" bytes
    255  */
    256 
    257 static bool rpc_grow_buffer(prs_struct *pdu, size_t size)
    258 {
    259         size_t extra_size;
    260 
    261         if (prs_data_size(pdu) >= size) {
    262                 return true;
    263         }
    264 
    265         extra_size = size - prs_data_size(pdu);
    266 
    267         if (!prs_force_grow(pdu, extra_size)) {
    268                 DEBUG(0, ("rpc_grow_buffer: Failed to grow parse struct by "
    269                           "%d bytes.\n", (int)extra_size));
    270                 return false;
    271         }
    272 
    273         DEBUG(5, ("rpc_grow_buffer: grew buffer by %d bytes to %u\n",
    274                   (int)extra_size, prs_data_size(pdu)));
    275         return true;
    276 }
    277 
    27863
    27964/*******************************************************************
     
    442227
    443228
    444 static NTSTATUS parse_rpc_header(struct rpc_pipe_client *cli,
    445                                  struct rpc_hdr_info *prhdr,
    446                                  prs_struct *pdu)
    447 {
    448         /*
    449          * This next call sets the endian bit correctly in current_pdu. We
    450          * will propagate this to rbuf later.
    451          */
    452 
    453         if(!smb_io_rpc_hdr("rpc_hdr   ", prhdr, pdu, 0)) {
    454                 DEBUG(0, ("get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
    455                 return NT_STATUS_BUFFER_TOO_SMALL;
    456         }
    457 
    458         if (prhdr->frag_len > cli->max_recv_frag) {
    459                 DEBUG(0, ("cli_pipe_get_current_pdu: Server sent fraglen %d,"
    460                           " we only allow %d\n", (int)prhdr->frag_len,
    461                           (int)cli->max_recv_frag));
    462                 return NT_STATUS_BUFFER_TOO_SMALL;
    463         }
    464 
    465         return NT_STATUS_OK;
    466 }
    467 
    468229/****************************************************************************
    469230 Try and get a PDU's worth of data from current_pdu. If not, then read more
     
    474235        struct event_context *ev;
    475236        struct rpc_pipe_client *cli;
    476         struct rpc_hdr_info *prhdr;
    477         prs_struct *pdu;
     237        uint16_t frag_len;
     238        DATA_BLOB *pdu;
    478239};
    479240
     
    484245                                                 struct event_context *ev,
    485246                                                 struct rpc_pipe_client *cli,
    486                                                  struct rpc_hdr_info *prhdr,
    487                                                  prs_struct *pdu)
     247                                                 DATA_BLOB *pdu)
    488248{
    489249        struct tevent_req *req, *subreq;
    490250        struct get_complete_frag_state *state;
    491         uint32_t pdu_len;
     251        size_t received;
    492252        NTSTATUS status;
    493253
     
    499259        state->ev = ev;
    500260        state->cli = cli;
    501         state->prhdr = prhdr;
     261        state->frag_len = RPC_HEADER_LEN;
    502262        state->pdu = pdu;
    503263
    504         pdu_len = prs_data_size(pdu);
    505         if (pdu_len < RPC_HEADER_LEN) {
    506                 if (!rpc_grow_buffer(pdu, RPC_HEADER_LEN)) {
     264        received = pdu->length;
     265        if (received < RPC_HEADER_LEN) {
     266                if (!data_blob_realloc(mem_ctx, pdu, RPC_HEADER_LEN)) {
    507267                        status = NT_STATUS_NO_MEMORY;
    508268                        goto post_status;
    509269                }
    510                 subreq = rpc_read_send(
    511                         state, state->ev,
    512                         state->cli->transport,
    513                         (uint8_t *)(prs_data_p(state->pdu) + pdu_len),
    514                         RPC_HEADER_LEN - pdu_len);
     270                subreq = rpc_read_send(state, state->ev,
     271                                        state->cli->transport,
     272                                        pdu->data + received,
     273                                        RPC_HEADER_LEN - received);
    515274                if (subreq == NULL) {
    516275                        status = NT_STATUS_NO_MEMORY;
     
    522281        }
    523282
    524         status = parse_rpc_header(cli, prhdr, pdu);
    525         if (!NT_STATUS_IS_OK(status)) {
    526                 goto post_status;
    527         }
     283        state->frag_len = dcerpc_get_frag_length(pdu);
    528284
    529285        /*
    530286         * Ensure we have frag_len bytes of data.
    531287         */
    532         if (pdu_len < prhdr->frag_len) {
    533                 if (!rpc_grow_buffer(pdu, prhdr->frag_len)) {
     288        if (received < state->frag_len) {
     289                if (!data_blob_realloc(NULL, pdu, state->frag_len)) {
    534290                        status = NT_STATUS_NO_MEMORY;
    535291                        goto post_status;
    536292                }
    537293                subreq = rpc_read_send(state, state->ev,
    538                                        state->cli->transport,
    539                                        (uint8_t *)(prs_data_p(pdu) + pdu_len),
    540                                        prhdr->frag_len - pdu_len);
     294                                        state->cli->transport,
     295                                        pdu->data + received,
     296                                        state->frag_len - received);
    541297                if (subreq == NULL) {
    542298                        status = NT_STATUS_NO_MEMORY;
     
    573329        }
    574330
    575         status = parse_rpc_header(state->cli, state->prhdr, state->pdu);
    576         if (!NT_STATUS_IS_OK(status)) {
    577                 tevent_req_nterror(req, status);
    578                 return;
    579         }
    580 
    581         if (!rpc_grow_buffer(state->pdu, state->prhdr->frag_len)) {
     331        state->frag_len = dcerpc_get_frag_length(state->pdu);
     332
     333        if (!data_blob_realloc(NULL, state->pdu, state->frag_len)) {
    582334                tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
    583335                return;
     
    589341         */
    590342
    591         subreq = rpc_read_send(
    592                 state, state->ev, state->cli->transport,
    593                 (uint8_t *)(prs_data_p(state->pdu) + RPC_HEADER_LEN),
    594                 state->prhdr->frag_len - RPC_HEADER_LEN);
     343        subreq = rpc_read_send(state, state->ev, state->cli->transport,
     344                                state->pdu->data + RPC_HEADER_LEN,
     345                                state->frag_len - RPC_HEADER_LEN);
    595346        if (tevent_req_nomem(subreq, req)) {
    596347                return;
     
    617368{
    618369        return tevent_req_simple_recv_ntstatus(req);
    619 }
    620 
    621 /****************************************************************************
    622  NTLMSSP specific sign/seal.
    623  Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
    624  In fact I should probably abstract these into identical pieces of code... JRA.
    625  ****************************************************************************/
    626 
    627 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
    628                                 prs_struct *current_pdu,
    629                                 uint8 *p_ss_padding_len)
    630 {
    631         RPC_HDR_AUTH auth_info;
    632         uint32 save_offset = prs_offset(current_pdu);
    633         uint32 auth_len = prhdr->auth_len;
    634         NTLMSSP_STATE *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
    635         unsigned char *data = NULL;
    636         size_t data_len;
    637         unsigned char *full_packet_data = NULL;
    638         size_t full_packet_data_len;
    639         DATA_BLOB auth_blob;
    640         NTSTATUS status;
    641 
    642         if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
    643             || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
    644                 return NT_STATUS_OK;
    645         }
    646 
    647         if (!ntlmssp_state) {
    648                 return NT_STATUS_INVALID_PARAMETER;
    649         }
    650 
    651         /* Ensure there's enough data for an authenticated response. */
    652         if ((auth_len > RPC_MAX_SIGN_SIZE) ||
    653                         (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
    654                 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
    655                         (unsigned int)auth_len ));
    656                 return NT_STATUS_BUFFER_TOO_SMALL;
    657         }
    658 
    659         /*
    660          * We need the full packet data + length (minus auth stuff) as well as the packet data + length
    661          * after the RPC header.
    662          * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
    663          * functions as NTLMv2 checks the rpc headers also.
    664          */
    665 
    666         data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
    667         data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
    668 
    669         full_packet_data = (unsigned char *)prs_data_p(current_pdu);
    670         full_packet_data_len = prhdr->frag_len - auth_len;
    671 
    672         /* Pull the auth header and the following data into a blob. */
    673         if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
    674                 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
    675                         (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
    676                 return NT_STATUS_BUFFER_TOO_SMALL;
    677         }
    678 
    679         if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
    680                 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
    681                 return NT_STATUS_BUFFER_TOO_SMALL;
    682         }
    683 
    684         auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
    685         auth_blob.length = auth_len;
    686 
    687         switch (cli->auth->auth_level) {
    688                 case DCERPC_AUTH_LEVEL_PRIVACY:
    689                         /* Data is encrypted. */
    690                         status = ntlmssp_unseal_packet(ntlmssp_state,
    691                                                         data, data_len,
    692                                                         full_packet_data,
    693                                                         full_packet_data_len,
    694                                                         &auth_blob);
    695                         if (!NT_STATUS_IS_OK(status)) {
    696                                 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
    697                                         "packet from %s. Error was %s.\n",
    698                                         rpccli_pipe_txt(talloc_tos(), cli),
    699                                         nt_errstr(status) ));
    700                                 return status;
    701                         }
    702                         break;
    703                 case DCERPC_AUTH_LEVEL_INTEGRITY:
    704                         /* Data is signed. */
    705                         status = ntlmssp_check_packet(ntlmssp_state,
    706                                                         data, data_len,
    707                                                         full_packet_data,
    708                                                         full_packet_data_len,
    709                                                         &auth_blob);
    710                         if (!NT_STATUS_IS_OK(status)) {
    711                                 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
    712                                         "packet from %s. Error was %s.\n",
    713                                         rpccli_pipe_txt(talloc_tos(), cli),
    714                                         nt_errstr(status) ));
    715                                 return status;
    716                         }
    717                         break;
    718                 default:
    719                         DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
    720                                   "auth level %d\n", cli->auth->auth_level));
    721                         return NT_STATUS_INVALID_INFO_CLASS;
    722         }
    723 
    724         /*
    725          * Return the current pointer to the data offset.
    726          */
    727 
    728         if(!prs_set_offset(current_pdu, save_offset)) {
    729                 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
    730                         (unsigned int)save_offset ));
    731                 return NT_STATUS_BUFFER_TOO_SMALL;
    732         }
    733 
    734         /*
    735          * Remember the padding length. We must remove it from the real data
    736          * stream once the sign/seal is done.
    737          */
    738 
    739         *p_ss_padding_len = auth_info.auth_pad_len;
    740 
    741         return NT_STATUS_OK;
    742 }
    743 
    744 /****************************************************************************
    745  schannel specific sign/seal.
    746  ****************************************************************************/
    747 
    748 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
    749                                 prs_struct *current_pdu,
    750                                 uint8 *p_ss_padding_len)
    751 {
    752         RPC_HDR_AUTH auth_info;
    753         uint32 auth_len = prhdr->auth_len;
    754         uint32 save_offset = prs_offset(current_pdu);
    755         struct schannel_state *schannel_auth =
    756                 cli->auth->a_u.schannel_auth;
    757         uint8_t *data;
    758         uint32 data_len;
    759         DATA_BLOB blob;
    760         NTSTATUS status;
    761 
    762         if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
    763             || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
    764                 return NT_STATUS_OK;
    765         }
    766 
    767         if (auth_len < RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
    768                 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
    769                 return NT_STATUS_INVALID_PARAMETER;
    770         }
    771 
    772         if (!schannel_auth) {
    773                 return NT_STATUS_INVALID_PARAMETER;
    774         }
    775 
    776         /* Ensure there's enough data for an authenticated response. */
    777         if ((auth_len > RPC_MAX_SIGN_SIZE) ||
    778                         (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
    779                 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
    780                         (unsigned int)auth_len ));
    781                 return NT_STATUS_INVALID_PARAMETER;
    782         }
    783 
    784         data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
    785 
    786         if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
    787                 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
    788                         (unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));
    789                 return NT_STATUS_BUFFER_TOO_SMALL;
    790         }
    791 
    792         if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
    793                 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
    794                 return NT_STATUS_BUFFER_TOO_SMALL;
    795         }
    796 
    797         if (auth_info.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
    798                 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
    799                         auth_info.auth_type));
    800                 return NT_STATUS_BUFFER_TOO_SMALL;
    801         }
    802 
    803         blob = data_blob_const(prs_data_p(current_pdu) + prs_offset(current_pdu), auth_len);
    804 
    805         if (DEBUGLEVEL >= 10) {
    806                 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
    807         }
    808 
    809         data = (uint8_t *)prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN;
    810 
    811         switch (cli->auth->auth_level) {
    812         case DCERPC_AUTH_LEVEL_PRIVACY:
    813                 status = netsec_incoming_packet(schannel_auth,
    814                                                 talloc_tos(),
    815                                                 true,
    816                                                 data,
    817                                                 data_len,
    818                                                 &blob);
    819                 break;
    820         case DCERPC_AUTH_LEVEL_INTEGRITY:
    821                 status = netsec_incoming_packet(schannel_auth,
    822                                                 talloc_tos(),
    823                                                 false,
    824                                                 data,
    825                                                 data_len,
    826                                                 &blob);
    827                 break;
    828         default:
    829                 status = NT_STATUS_INTERNAL_ERROR;
    830                 break;
    831         }
    832 
    833         if (!NT_STATUS_IS_OK(status)) {
    834                 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
    835                                 "Connection to %s (%s).\n",
    836                                 rpccli_pipe_txt(talloc_tos(), cli),
    837                                 nt_errstr(status)));
    838                 return NT_STATUS_INVALID_PARAMETER;
    839         }
    840 
    841         /*
    842          * Return the current pointer to the data offset.
    843          */
    844 
    845         if(!prs_set_offset(current_pdu, save_offset)) {
    846                 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
    847                         (unsigned int)save_offset ));
    848                 return NT_STATUS_BUFFER_TOO_SMALL;
    849         }
    850 
    851         /*
    852          * Remember the padding length. We must remove it from the real data
    853          * stream once the sign/seal is done.
    854          */
    855 
    856         *p_ss_padding_len = auth_info.auth_pad_len;
    857 
    858         return NT_STATUS_OK;
    859 }
    860 
    861 /****************************************************************************
    862  Do the authentication checks on an incoming pdu. Check sign and unseal etc.
    863  ****************************************************************************/
    864 
    865 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
    866                                 prs_struct *current_pdu,
    867                                 uint8 *p_ss_padding_len)
    868 {
    869         NTSTATUS ret = NT_STATUS_OK;
    870 
    871         /* Paranioa checks for auth_len. */
    872         if (prhdr->auth_len) {
    873                 if (prhdr->auth_len > prhdr->frag_len) {
    874                         return NT_STATUS_INVALID_PARAMETER;
    875                 }
    876 
    877                 if (prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_len ||
    878                                 prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
    879                         /* Integer wrap attempt. */
    880                         return NT_STATUS_INVALID_PARAMETER;
    881                 }
    882         }
    883 
    884         /*
    885          * Now we have a complete RPC request PDU fragment, try and verify any auth data.
    886          */
    887 
    888         switch(cli->auth->auth_type) {
    889                 case PIPE_AUTH_TYPE_NONE:
    890                         if (prhdr->auth_len) {
    891                                 DEBUG(3, ("cli_pipe_validate_rpc_response: "
    892                                           "Connection to %s - got non-zero "
    893                                           "auth len %u.\n",
    894                                         rpccli_pipe_txt(talloc_tos(), cli),
    895                                         (unsigned int)prhdr->auth_len ));
    896                                 return NT_STATUS_INVALID_PARAMETER;
    897                         }
    898                         break;
    899 
    900                 case PIPE_AUTH_TYPE_NTLMSSP:
    901                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
    902                         ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
    903                         if (!NT_STATUS_IS_OK(ret)) {
    904                                 return ret;
    905                         }
    906                         break;
    907 
    908                 case PIPE_AUTH_TYPE_SCHANNEL:
    909                         ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
    910                         if (!NT_STATUS_IS_OK(ret)) {
    911                                 return ret;
    912                         }
    913                         break;
    914 
    915                 case PIPE_AUTH_TYPE_KRB5:
    916                 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
    917                 default:
    918                         DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
    919                                   "to %s - unknown internal auth type %u.\n",
    920                                   rpccli_pipe_txt(talloc_tos(), cli),
    921                                   cli->auth->auth_type ));
    922                         return NT_STATUS_INVALID_INFO_CLASS;
    923         }
    924 
    925         return NT_STATUS_OK;
    926370}
    927371
     
    930374 ****************************************************************************/
    931375
    932 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
    933                         prs_struct *current_pdu,
    934                         uint8 expected_pkt_type,
    935                         char **ppdata,
    936                         uint32 *pdata_len,
    937                         prs_struct *return_data)
    938 {
    939 
     376static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
     377                                                struct rpc_pipe_client *cli,
     378                                                struct ncacn_packet *pkt,
     379                                                DATA_BLOB *pdu,
     380                                                uint8_t expected_pkt_type,
     381                                                DATA_BLOB *rdata,
     382                                                DATA_BLOB *reply_pdu)
     383{
     384        struct dcerpc_response *r;
    940385        NTSTATUS ret = NT_STATUS_OK;
    941         uint32 current_pdu_len = prs_data_size(current_pdu);
    942 
    943         if (current_pdu_len != prhdr->frag_len) {
    944                 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
    945                         (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
    946                 return NT_STATUS_INVALID_PARAMETER;
    947         }
     386        size_t pad_len = 0;
    948387
    949388        /*
     
    951390         * header. Just in case the caller wants it.
    952391         */
    953         *ppdata = prs_data_p(current_pdu);
    954         *pdata_len = current_pdu_len;
     392        *rdata = *pdu;
    955393
    956394        /* Ensure we have the correct type. */
    957         switch (prhdr->pkt_type) {
    958                 case DCERPC_PKT_ALTER_RESP:
    959                 case DCERPC_PKT_BIND_ACK:
    960 
    961                         /* Alter context and bind ack share the same packet definitions. */
    962                         break;
    963 
    964 
    965                 case DCERPC_PKT_RESPONSE:
    966                 {
    967                         RPC_HDR_RESP rhdr_resp;
    968                         uint8 ss_padding_len = 0;
    969 
    970                         if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
    971                                 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
    972                                 return NT_STATUS_BUFFER_TOO_SMALL;
    973                         }
    974 
    975                         /* Here's where we deal with incoming sign/seal. */
    976                         ret = cli_pipe_validate_rpc_response(cli, prhdr,
    977                                         current_pdu, &ss_padding_len);
    978                         if (!NT_STATUS_IS_OK(ret)) {
    979                                 return ret;
    980                         }
    981 
    982                         /* Point the return values at the NDR data. Remember to remove any ss padding. */
    983                         *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
    984 
    985                         if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
    986                                 return NT_STATUS_BUFFER_TOO_SMALL;
    987                         }
    988 
    989                         *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
    990 
    991                         /* Remember to remove the auth footer. */
    992                         if (prhdr->auth_len) {
    993                                 /* We've already done integer wrap tests on auth_len in
    994                                         cli_pipe_validate_rpc_response(). */
    995                                 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
    996                                         return NT_STATUS_BUFFER_TOO_SMALL;
    997                                 }
    998                                 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
    999                         }
    1000 
    1001                         DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
    1002                                 current_pdu_len, *pdata_len, ss_padding_len ));
    1003 
    1004                         /*
    1005                          * If this is the first reply, and the allocation hint is reasonably, try and
    1006                          * set up the return_data parse_struct to the correct size.
    1007                          */
    1008 
    1009                         if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
    1010                                 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
    1011                                         DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
    1012                                                 "too large to allocate\n",
    1013                                                 (unsigned int)rhdr_resp.alloc_hint ));
    1014                                         return NT_STATUS_NO_MEMORY;
    1015                                 }
    1016                         }
    1017 
    1018                         break;
     395        switch (pkt->ptype) {
     396        case DCERPC_PKT_ALTER_RESP:
     397        case DCERPC_PKT_BIND_ACK:
     398
     399                /* Client code never receives this kind of packets */
     400                break;
     401
     402
     403        case DCERPC_PKT_RESPONSE:
     404
     405                r = &pkt->u.response;
     406
     407                /* Here's where we deal with incoming sign/seal. */
     408                ret = dcerpc_check_auth(cli->auth, pkt,
     409                                        &r->stub_and_verifier,
     410                                        DCERPC_RESPONSE_LENGTH,
     411                                        pdu, &pad_len);
     412                if (!NT_STATUS_IS_OK(ret)) {
     413                        return ret;
    1019414                }
    1020415
    1021                 case DCERPC_PKT_BIND_NAK:
    1022                         DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
    1023                                   "received from %s!\n",
    1024                                   rpccli_pipe_txt(talloc_tos(), cli)));
    1025                         /* Use this for now... */
    1026                         return NT_STATUS_NETWORK_ACCESS_DENIED;
    1027 
    1028                 case DCERPC_PKT_FAULT:
    1029                 {
    1030                         RPC_HDR_RESP rhdr_resp;
    1031                         RPC_HDR_FAULT fault_resp;
    1032 
    1033                         if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
    1034                                 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
    1035                                 return NT_STATUS_BUFFER_TOO_SMALL;
    1036                         }
    1037 
    1038                         if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
    1039                                 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
    1040                                 return NT_STATUS_BUFFER_TOO_SMALL;
    1041                         }
    1042 
    1043                         DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
    1044                                   "code %s received from %s!\n",
    1045                                 dcerpc_errstr(talloc_tos(), NT_STATUS_V(fault_resp.status)),
    1046                                 rpccli_pipe_txt(talloc_tos(), cli)));
    1047                         if (NT_STATUS_IS_OK(fault_resp.status)) {
    1048                                 return NT_STATUS_UNSUCCESSFUL;
    1049                         } else {
    1050                                 return fault_resp.status;
     416                if (pkt->frag_length < DCERPC_RESPONSE_LENGTH + pad_len) {
     417                        return NT_STATUS_BUFFER_TOO_SMALL;
     418                }
     419
     420                /* Point the return values at the NDR data. */
     421                rdata->data = r->stub_and_verifier.data;
     422
     423                if (pkt->auth_length) {
     424                        /* We've already done integer wrap tests in
     425                         * dcerpc_check_auth(). */
     426                        rdata->length = r->stub_and_verifier.length
     427                                         - pad_len
     428                                         - DCERPC_AUTH_TRAILER_LENGTH
     429                                         - pkt->auth_length;
     430                } else {
     431                        rdata->length = r->stub_and_verifier.length;
     432                }
     433
     434                DEBUG(10, ("Got pdu len %lu, data_len %lu, ss_len %u\n",
     435                           (long unsigned int)pdu->length,
     436                           (long unsigned int)rdata->length,
     437                           (unsigned int)pad_len));
     438
     439                /*
     440                 * If this is the first reply, and the allocation hint is
     441                 * reasonable, try and set up the reply_pdu DATA_BLOB to the
     442                 * correct size.
     443                 */
     444
     445                if ((reply_pdu->length == 0) &&
     446                    r->alloc_hint && (r->alloc_hint < 15*1024*1024)) {
     447                        if (!data_blob_realloc(mem_ctx, reply_pdu,
     448                                                        r->alloc_hint)) {
     449                                DEBUG(0, ("reply alloc hint %d too "
     450                                          "large to allocate\n",
     451                                          (int)r->alloc_hint));
     452                                return NT_STATUS_NO_MEMORY;
    1051453                        }
    1052454                }
    1053455
    1054                 default:
    1055                         DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
    1056                                 "from %s!\n",
    1057                                 (unsigned int)prhdr->pkt_type,
    1058                                 rpccli_pipe_txt(talloc_tos(), cli)));
    1059                         return NT_STATUS_INVALID_INFO_CLASS;
    1060         }
    1061 
    1062         if (prhdr->pkt_type != expected_pkt_type) {
    1063                 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
    1064                           "got an unexpected RPC packet type - %u, not %u\n",
    1065                         rpccli_pipe_txt(talloc_tos(), cli),
    1066                         prhdr->pkt_type,
    1067                         expected_pkt_type));
     456                break;
     457
     458        case DCERPC_PKT_BIND_NAK:
     459                DEBUG(1, (__location__ ": Bind NACK received from %s!\n",
     460                          rpccli_pipe_txt(talloc_tos(), cli)));
     461                /* Use this for now... */
     462                return NT_STATUS_NETWORK_ACCESS_DENIED;
     463
     464        case DCERPC_PKT_FAULT:
     465
     466                DEBUG(1, (__location__ ": RPC fault code %s received "
     467                          "from %s!\n",
     468                          dcerpc_errstr(talloc_tos(),
     469                          pkt->u.fault.status),
     470                          rpccli_pipe_txt(talloc_tos(), cli)));
     471
     472                return dcerpc_fault_to_nt_status(pkt->u.fault.status);
     473
     474        default:
     475                DEBUG(0, (__location__ "Unknown packet type %u received "
     476                          "from %s!\n",
     477                          (unsigned int)pkt->ptype,
     478                          rpccli_pipe_txt(talloc_tos(), cli)));
     479                return NT_STATUS_INVALID_INFO_CLASS;
     480        }
     481
     482        if (pkt->ptype != expected_pkt_type) {
     483                DEBUG(3, (__location__ ": Connection to %s got an unexpected "
     484                          "RPC packet type - %u, not %u\n",
     485                          rpccli_pipe_txt(talloc_tos(), cli),
     486                          pkt->ptype, expected_pkt_type));
    1068487                return NT_STATUS_INVALID_INFO_CLASS;
    1069488        }
     
    1073492           it before. */
    1074493
    1075         if ((prhdr->pkt_type == DCERPC_PKT_BIND_ACK) && !(prhdr->flags & DCERPC_PFC_FLAG_LAST)) {
    1076                 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
    1077                         "setting fragment first/last ON.\n"));
    1078                 prhdr->flags |= DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST;
    1079         }
    1080 
    1081         return NT_STATUS_OK;
    1082 }
    1083 
    1084 /****************************************************************************
    1085  Ensure we eat the just processed pdu from the current_pdu prs_struct.
    1086  Normally the frag_len and buffer size will match, but on the first trans
    1087  reply there is a theoretical chance that buffer size > frag_len, so we must
    1088  deal with that.
    1089  ****************************************************************************/
    1090 
    1091 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
    1092 {
    1093         uint32 current_pdu_len = prs_data_size(current_pdu);
    1094 
    1095         if (current_pdu_len < prhdr->frag_len) {
    1096                 return NT_STATUS_BUFFER_TOO_SMALL;
    1097         }
    1098 
    1099         /* Common case. */
    1100         if (current_pdu_len == (uint32)prhdr->frag_len) {
    1101                 prs_mem_free(current_pdu);
    1102                 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
    1103                 /* Make current_pdu dynamic with no memory. */
    1104                 prs_give_memory(current_pdu, 0, 0, True);
    1105                 return NT_STATUS_OK;
    1106         }
    1107 
    1108         /*
    1109          * Oh no ! More data in buffer than we processed in current pdu.
    1110          * Cheat. Move the data down and shrink the buffer.
    1111          */
    1112 
    1113         memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
    1114                         current_pdu_len - prhdr->frag_len);
    1115 
    1116         /* Remember to set the read offset back to zero. */
    1117         prs_set_offset(current_pdu, 0);
    1118 
    1119         /* Shrink the buffer. */
    1120         if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
    1121                 return NT_STATUS_BUFFER_TOO_SMALL;
     494        if ((pkt->ptype == DCERPC_PKT_BIND_ACK) &&
     495            !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
     496                DEBUG(5, (__location__ ": bug in server (AS/U?), setting "
     497                          "fragment first/last ON.\n"));
     498                pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
    1122499        }
    1123500
     
    1188565        tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
    1189566        return req;
    1190 
    1191         status = NT_STATUS_INVALID_PARAMETER;
    1192567
    1193568 post_status:
     
    1287662
    1288663/****************************************************************************
    1289  Send data on an rpc pipe via trans. The prs_struct data must be the last
     664 Send data on an rpc pipe via trans. The data must be the last
    1290665 pdu fragment of an NDR data stream.
    1291666
     
    1317692        uint8_t expected_pkt_type;
    1318693
    1319         prs_struct incoming_frag;
    1320         struct rpc_hdr_info rhdr;
    1321 
    1322         prs_struct incoming_pdu;        /* Incoming reply */
    1323         uint32_t incoming_pdu_offset;
     694        DATA_BLOB incoming_frag;
     695        struct ncacn_packet *pkt;
     696
     697        /* Incoming reply */
     698        DATA_BLOB reply_pdu;
     699        size_t reply_pdu_offset;
     700        uint8_t endianess;
    1324701};
    1325 
    1326 static int rpc_api_pipe_state_destructor(struct rpc_api_pipe_state *state)
    1327 {
    1328         prs_mem_free(&state->incoming_frag);
    1329         prs_mem_free(&state->incoming_pdu);
    1330         return 0;
    1331 }
    1332702
    1333703static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
    1334704static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
     705static void rpc_api_pipe_auth3_done(struct tevent_req *subreq);
    1335706
    1336707static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
    1337708                                            struct event_context *ev,
    1338709                                            struct rpc_pipe_client *cli,
    1339                                             prs_struct *data, /* Outgoing PDU */
     710                                            DATA_BLOB *data, /* Outgoing PDU */
    1340711                                            uint8_t expected_pkt_type)
    1341712{
     
    1352723        state->cli = cli;
    1353724        state->expected_pkt_type = expected_pkt_type;
    1354         state->incoming_pdu_offset = 0;
    1355 
    1356         prs_init_empty(&state->incoming_frag, state, UNMARSHALL);
    1357 
    1358         prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
    1359         /* Make incoming_pdu dynamic with no memory. */
    1360         prs_give_memory(&state->incoming_pdu, NULL, 0, true);
    1361 
    1362         talloc_set_destructor(state, rpc_api_pipe_state_destructor);
     725        state->incoming_frag = data_blob_null;
     726        state->reply_pdu = data_blob_null;
     727        state->reply_pdu_offset = 0;
     728        state->endianess = DCERPC_DREP_LE;
    1363729
    1364730        /*
    1365731         * Ensure we're not sending too much.
    1366732         */
    1367         if (prs_offset(data) > cli->max_xmit_frag) {
     733        if (data->length > cli->max_xmit_frag) {
    1368734                status = NT_STATUS_INVALID_PARAMETER;
    1369735                goto post_status;
     
    1372738        DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
    1373739
    1374         max_recv_frag = cli->max_recv_frag;
    1375 
    1376 #if 0
    1377         max_recv_frag = RPC_HEADER_LEN + 10 + (sys_random() % 32);
    1378 #endif
     740        if (state->expected_pkt_type == DCERPC_PKT_AUTH3) {
     741                subreq = rpc_write_send(state, ev, cli->transport,
     742                                        data->data, data->length);
     743                if (subreq == NULL) {
     744                        goto fail;
     745                }
     746                tevent_req_set_callback(subreq, rpc_api_pipe_auth3_done, req);
     747                return req;
     748        }
     749
     750        /* get the header first, then fetch the rest once we have
     751         * the frag_length available */
     752        max_recv_frag = RPC_HEADER_LEN;
    1379753
    1380754        subreq = cli_api_pipe_send(state, ev, cli->transport,
    1381                                    (uint8_t *)prs_data_p(data),
    1382                                    prs_offset(data), max_recv_frag);
     755                                   data->data, data->length, max_recv_frag);
    1383756        if (subreq == NULL) {
    1384757                goto fail;
     
    1395768}
    1396769
     770static void rpc_api_pipe_auth3_done(struct tevent_req *subreq)
     771{
     772        struct tevent_req *req =
     773                tevent_req_callback_data(subreq,
     774                struct tevent_req);
     775        NTSTATUS status;
     776
     777        status = rpc_write_recv(subreq);
     778        TALLOC_FREE(subreq);
     779        if (!NT_STATUS_IS_OK(status)) {
     780                tevent_req_nterror(req, status);
     781                return;
     782        }
     783
     784        tevent_req_done(req);
     785}
     786
    1397787static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
    1398788{
     
    1404794        uint8_t *rdata = NULL;
    1405795        uint32_t rdata_len = 0;
    1406         char *rdata_copy;
    1407796
    1408797        status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
     
    1422811
    1423812        /*
    1424          * Give the memory received from cli_trans as dynamic to the current
    1425          * pdu. Duplicating it sucks, but prs_struct doesn't know about talloc
    1426          * :-(
     813         * Move data on state->incoming_frag.
    1427814         */
    1428         rdata_copy = (char *)memdup(rdata, rdata_len);
    1429         TALLOC_FREE(rdata);
    1430         if (tevent_req_nomem(rdata_copy, req)) {
    1431                 return;
    1432         }
    1433         prs_give_memory(&state->incoming_frag, rdata_copy, rdata_len, true);
     815        state->incoming_frag.data = talloc_move(state, &rdata);
     816        state->incoming_frag.length = rdata_len;
     817        if (!state->incoming_frag.data) {
     818                tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
     819                return;
     820        }
    1434821
    1435822        /* Ensure we have enough data for a pdu. */
    1436823        subreq = get_complete_frag_send(state, state->ev, state->cli,
    1437                                         &state->rhdr, &state->incoming_frag);
     824                                        &state->incoming_frag);
    1438825        if (tevent_req_nomem(subreq, req)) {
    1439826                return;
     
    1449836                req, struct rpc_api_pipe_state);
    1450837        NTSTATUS status;
    1451         char *rdata = NULL;
    1452         uint32_t rdata_len = 0;
     838        DATA_BLOB rdata = data_blob_null;
    1453839
    1454840        status = get_complete_frag_recv(subreq);
     
    1461847        }
    1462848
    1463         status = cli_pipe_validate_current_pdu(
    1464                 state->cli, &state->rhdr, &state->incoming_frag,
    1465                 state->expected_pkt_type, &rdata, &rdata_len,
    1466                 &state->incoming_pdu);
     849        state->pkt = talloc(state, struct ncacn_packet);
     850        if (!state->pkt) {
     851                tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
     852                return;
     853        }
     854
     855        status = dcerpc_pull_ncacn_packet(state->pkt,
     856                                          &state->incoming_frag,
     857                                          state->pkt,
     858                                          !state->endianess);
     859        if (!NT_STATUS_IS_OK(status)) {
     860                tevent_req_nterror(req, status);
     861                return;
     862        }
     863
     864        if (state->incoming_frag.length != state->pkt->frag_length) {
     865                DEBUG(5, ("Incorrect pdu length %u, expected %u\n",
     866                          (unsigned int)state->incoming_frag.length,
     867                          (unsigned int)state->pkt->frag_length));
     868                tevent_req_nterror(req,  NT_STATUS_INVALID_PARAMETER);
     869                return;
     870        }
     871
     872        status = cli_pipe_validate_current_pdu(state,
     873                                                state->cli, state->pkt,
     874                                                &state->incoming_frag,
     875                                                state->expected_pkt_type,
     876                                                &rdata,
     877                                                &state->reply_pdu);
    1467878
    1468879        DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
    1469                   (unsigned)prs_data_size(&state->incoming_frag),
    1470                   (unsigned)state->incoming_pdu_offset,
     880                  (unsigned)state->incoming_frag.length,
     881                  (unsigned)state->reply_pdu_offset,
    1471882                  nt_errstr(status)));
    1472883
     
    1476887        }
    1477888
    1478         if ((state->rhdr.flags & DCERPC_PFC_FLAG_FIRST)
    1479             && (state->rhdr.pack_type[0] == 0)) {
     889        if ((state->pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST)
     890            && (state->pkt->drep[0] != DCERPC_DREP_LE)) {
    1480891                /*
    1481892                 * Set the data type correctly for big-endian data on the
     
    1485896                          "big-endian.\n",
    1486897                          rpccli_pipe_txt(talloc_tos(), state->cli)));
    1487                 prs_set_endian_data(&state->incoming_pdu, RPC_BIG_ENDIAN);
     898                state->endianess = 0x00; /* BIG ENDIAN */
    1488899        }
    1489900        /*
    1490901         * Check endianness on subsequent packets.
    1491902         */
    1492         if (state->incoming_frag.bigendian_data
    1493             != state->incoming_pdu.bigendian_data) {
     903        if (state->endianess != state->pkt->drep[0]) {
    1494904                DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
    1495905                         "%s\n",
    1496                          state->incoming_pdu.bigendian_data?"big":"little",
    1497                          state->incoming_frag.bigendian_data?"big":"little"));
     906                         state->endianess?"little":"big",
     907                         state->pkt->drep[0]?"little":"big"));
    1498908                tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
    1499909                return;
     
    1501911
    1502912        /* Now copy the data portion out of the pdu into rbuf. */
    1503         if (!prs_force_grow(&state->incoming_pdu, rdata_len)) {
    1504                 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
    1505                 return;
    1506         }
    1507 
    1508         memcpy(prs_data_p(&state->incoming_pdu) + state->incoming_pdu_offset,
    1509                rdata, (size_t)rdata_len);
    1510         state->incoming_pdu_offset += rdata_len;
    1511 
    1512         status = cli_pipe_reset_current_pdu(state->cli, &state->rhdr,
    1513                                             &state->incoming_frag);
    1514         if (!NT_STATUS_IS_OK(status)) {
    1515                 tevent_req_nterror(req, status);
    1516                 return;
    1517         }
    1518 
    1519         if (state->rhdr.flags & DCERPC_PFC_FLAG_LAST) {
     913        if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) {
     914                if (!data_blob_realloc(NULL, &state->reply_pdu,
     915                                state->reply_pdu_offset + rdata.length)) {
     916                        tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
     917                        return;
     918                }
     919        }
     920
     921        memcpy(state->reply_pdu.data + state->reply_pdu_offset,
     922                rdata.data, rdata.length);
     923        state->reply_pdu_offset += rdata.length;
     924
     925        /* reset state->incoming_frag, there is no need to free it,
     926         * it will be reallocated to the right size the next time
     927         * it is used */
     928        state->incoming_frag.length = 0;
     929
     930        if (state->pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
     931                /* make sure the pdu length is right now that we
     932                 * have all the data available (alloc hint may
     933                 * have allocated more than was actually used) */
     934                state->reply_pdu.length = state->reply_pdu_offset;
    1520935                DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
    1521936                          rpccli_pipe_txt(talloc_tos(), state->cli),
    1522                           (unsigned)prs_data_size(&state->incoming_pdu)));
     937                          (unsigned)state->reply_pdu.length));
    1523938                tevent_req_done(req);
    1524939                return;
     
    1526941
    1527942        subreq = get_complete_frag_send(state, state->ev, state->cli,
    1528                                         &state->rhdr, &state->incoming_frag);
     943                                        &state->incoming_frag);
    1529944        if (tevent_req_nomem(subreq, req)) {
    1530945                return;
     
    1534949
    1535950static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
    1536                                   prs_struct *reply_pdu)
     951                                  struct ncacn_packet **pkt,
     952                                  DATA_BLOB *reply_pdu)
    1537953{
    1538954        struct rpc_api_pipe_state *state = tevent_req_data(
     
    1544960        }
    1545961
    1546         *reply_pdu = state->incoming_pdu;
    1547         reply_pdu->mem_ctx = mem_ctx;
    1548 
    1549         /*
    1550          * Prevent state->incoming_pdu from being freed in
    1551          * rpc_api_pipe_state_destructor()
    1552          */
    1553         prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
     962        /* return data to caller and assign it ownership of memory */
     963        if (reply_pdu) {
     964                reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
     965                reply_pdu->length = state->reply_pdu.length;
     966                state->reply_pdu.length = 0;
     967        } else {
     968                data_blob_free(&state->reply_pdu);
     969        }
     970
     971        if (pkt) {
     972                *pkt = talloc_steal(mem_ctx, state->pkt);
     973        }
     974
     975        return NT_STATUS_OK;
     976}
     977
     978/*******************************************************************
     979 Creates spnego auth bind.
     980 ********************************************************************/
     981
     982static NTSTATUS create_spnego_auth_bind_req(TALLOC_CTX *mem_ctx,
     983                                            struct pipe_auth_data *auth,
     984                                            DATA_BLOB *auth_token)
     985{
     986        struct spnego_context *spnego_ctx;
     987        DATA_BLOB in_token = data_blob_null;
     988        NTSTATUS status;
     989
     990        spnego_ctx = talloc_get_type_abort(auth->auth_ctx,
     991                                           struct spnego_context);
     992
     993        /* Negotiate the initial auth token */
     994        status = spnego_get_client_auth_token(mem_ctx, spnego_ctx,
     995                                              &in_token, auth_token);
     996        if (!NT_STATUS_IS_OK(status)) {
     997                return status;
     998        }
     999
     1000        DEBUG(5, ("Created GSS Authentication Token:\n"));
     1001        dump_data(5, auth_token->data, auth_token->length);
    15541002
    15551003        return NT_STATUS_OK;
     
    15601008 ********************************************************************/
    15611009
    1562 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
    1563                                                 enum dcerpc_AuthLevel auth_level,
    1564                                                 RPC_HDR_AUTH *pauth_out,
    1565                                                 prs_struct *auth_data)
    1566 {
    1567 #ifdef HAVE_KRB5
    1568         int ret;
    1569         struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
    1570         DATA_BLOB tkt = data_blob_null;
    1571         DATA_BLOB tkt_wrapped = data_blob_null;
    1572 
    1573         /* We may change the pad length before marshalling. */
    1574         init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_KRB5, (int)auth_level, 0, 1);
    1575 
    1576         DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
    1577                 a->service_principal ));
    1578 
    1579         /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
    1580 
    1581         ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
    1582                         &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL, NULL);
    1583 
    1584         if (ret) {
    1585                 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
    1586                         "failed with %s\n",
    1587                         a->service_principal,
    1588                         error_message(ret) ));
    1589 
    1590                 data_blob_free(&tkt);
    1591                 prs_mem_free(auth_data);
    1592                 return NT_STATUS_INVALID_PARAMETER;
    1593         }
    1594 
    1595         /* wrap that up in a nice GSS-API wrapping */
    1596         tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
    1597 
    1598         data_blob_free(&tkt);
    1599 
    1600         /* Auth len in the rpc header doesn't include auth_header. */
    1601         if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
    1602                 data_blob_free(&tkt_wrapped);
    1603                 prs_mem_free(auth_data);
    1604                 return NT_STATUS_NO_MEMORY;
    1605         }
    1606 
    1607         DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
    1608         dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
    1609 
    1610         data_blob_free(&tkt_wrapped);
    1611         return NT_STATUS_OK;
    1612 #else
    1613         return NT_STATUS_INVALID_PARAMETER;
    1614 #endif
    1615 }
    1616 
    1617 /*******************************************************************
    1618  Creates SPNEGO NTLMSSP auth bind.
    1619  ********************************************************************/
    1620 
    1621 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
    1622                                                 enum dcerpc_AuthLevel auth_level,
    1623                                                 RPC_HDR_AUTH *pauth_out,
    1624                                                 prs_struct *auth_data)
    1625 {
    1626         NTSTATUS nt_status;
    1627         DATA_BLOB null_blob = data_blob_null;
    1628         DATA_BLOB request = data_blob_null;
    1629         DATA_BLOB spnego_msg = data_blob_null;
    1630 
    1631         /* We may change the pad length before marshalling. */
    1632         init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1);
    1633 
    1634         DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
    1635         nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
    1636                                         null_blob,
    1637                                         &request);
    1638 
    1639         if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
    1640                 data_blob_free(&request);
    1641                 prs_mem_free(auth_data);
    1642                 return nt_status;
    1643         }
    1644 
    1645         /* Wrap this in SPNEGO. */
    1646         spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
    1647 
    1648         data_blob_free(&request);
    1649 
    1650         /* Auth len in the rpc header doesn't include auth_header. */
    1651         if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
    1652                 data_blob_free(&spnego_msg);
    1653                 prs_mem_free(auth_data);
    1654                 return NT_STATUS_NO_MEMORY;
    1655         }
    1656 
    1657         DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
    1658         dump_data(5, spnego_msg.data, spnego_msg.length);
    1659 
    1660         data_blob_free(&spnego_msg);
     1010static NTSTATUS create_gssapi_auth_bind_req(TALLOC_CTX *mem_ctx,
     1011                                            struct pipe_auth_data *auth,
     1012                                            DATA_BLOB *auth_token)
     1013{
     1014        struct gse_context *gse_ctx;
     1015        DATA_BLOB in_token = data_blob_null;
     1016        NTSTATUS status;
     1017
     1018        gse_ctx = talloc_get_type_abort(auth->auth_ctx,
     1019                                        struct gse_context);
     1020
     1021        /* Negotiate the initial auth token */
     1022        status = gse_get_client_auth_token(mem_ctx, gse_ctx,
     1023                                           &in_token,
     1024                                           auth_token);
     1025        if (!NT_STATUS_IS_OK(status)) {
     1026                return status;
     1027        }
     1028
     1029        DEBUG(5, ("Created GSS Authentication Token:\n"));
     1030        dump_data(5, auth_token->data, auth_token->length);
     1031
    16611032        return NT_STATUS_OK;
    16621033}
     
    16661037 ********************************************************************/
    16671038
    1668 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
    1669                                                 enum dcerpc_AuthLevel auth_level,
    1670                                                 RPC_HDR_AUTH *pauth_out,
    1671                                                 prs_struct *auth_data)
    1672 {
    1673         NTSTATUS nt_status;
     1039static NTSTATUS create_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
     1040                                                 DATA_BLOB *auth_token)
     1041{
     1042        struct auth_ntlmssp_state *ntlmssp_ctx;
    16741043        DATA_BLOB null_blob = data_blob_null;
    1675         DATA_BLOB request = data_blob_null;
    1676 
    1677         /* We may change the pad length before marshalling. */
    1678         init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_NTLMSSP, (int)auth_level, 0, 1);
     1044        NTSTATUS status;
     1045
     1046        ntlmssp_ctx = talloc_get_type_abort(cli->auth->auth_ctx,
     1047                                            struct auth_ntlmssp_state);
    16791048
    16801049        DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
    1681         nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
    1682                                         null_blob,
    1683                                         &request);
    1684 
    1685         if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
    1686                 data_blob_free(&request);
    1687                 prs_mem_free(auth_data);
    1688                 return nt_status;
    1689         }
    1690 
    1691         /* Auth len in the rpc header doesn't include auth_header. */
    1692         if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
    1693                 data_blob_free(&request);
    1694                 prs_mem_free(auth_data);
    1695                 return NT_STATUS_NO_MEMORY;
     1050        status = auth_ntlmssp_update(ntlmssp_ctx, null_blob, auth_token);
     1051
     1052        if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
     1053                data_blob_free(auth_token);
     1054                return status;
    16961055        }
    16971056
    16981057        DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
    1699         dump_data(5, request.data, request.length);
    1700 
    1701         data_blob_free(&request);
     1058        dump_data(5, auth_token->data, auth_token->length);
     1059
    17021060        return NT_STATUS_OK;
    17031061}
     
    17071065 ********************************************************************/
    17081066
    1709 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
    1710                                                 enum dcerpc_AuthLevel auth_level,
    1711                                                 RPC_HDR_AUTH *pauth_out,
    1712                                                 prs_struct *auth_data)
    1713 {
     1067static NTSTATUS create_schannel_auth_rpc_bind_req(struct rpc_pipe_client *cli,
     1068                                                  DATA_BLOB *auth_token)
     1069{
     1070        NTSTATUS status;
    17141071        struct NL_AUTH_MESSAGE r;
    1715         enum ndr_err_code ndr_err;
    1716         DATA_BLOB blob;
    1717 
    1718         /* We may change the pad length before marshalling. */
    1719         init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_SCHANNEL, (int)auth_level, 0, 1);
    17201072
    17211073        /* Use lp_workgroup() if domain not specified */
     
    17381090        r.oem_netbios_computer.a        = global_myname();
    17391091
    1740         ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), NULL, &r,
    1741                        (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
    1742         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    1743                 DEBUG(0,("Failed to marshall NL_AUTH_MESSAGE.\n"));
    1744                 prs_mem_free(auth_data);
    1745                 return ndr_map_error2ntstatus(ndr_err);
    1746         }
    1747 
    1748         if (DEBUGLEVEL >= 10) {
    1749                 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &r);
    1750         }
    1751 
    1752         if (!prs_copy_data_in(auth_data, (const char *)blob.data, blob.length))
    1753         {
    1754                 prs_mem_free(auth_data);
    1755                 return NT_STATUS_NO_MEMORY;
     1092        status = dcerpc_push_schannel_bind(cli, &r, auth_token);
     1093        if (!NT_STATUS_IS_OK(status)) {
     1094                return status;
    17561095        }
    17571096
     
    17631102 ********************************************************************/
    17641103
    1765 static NTSTATUS create_bind_or_alt_ctx_internal(enum dcerpc_pkt_type pkt_type,
    1766                                                 prs_struct *rpc_out,
     1104static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx,
     1105                                                enum dcerpc_pkt_type ptype,
    17671106                                                uint32 rpc_call_id,
    17681107                                                const struct ndr_syntax_id *abstract,
    17691108                                                const struct ndr_syntax_id *transfer,
    1770                                                 RPC_HDR_AUTH *phdr_auth,
    1771                                                 prs_struct *pauth_info)
    1772 {
    1773         RPC_HDR hdr;
    1774         RPC_HDR_RB hdr_rb;
    1775         RPC_CONTEXT rpc_ctx;
    1776         uint16 auth_len = prs_offset(pauth_info);
    1777         uint8 ss_padding_len = 0;
    1778         uint16 frag_len = 0;
    1779 
    1780         /* create the RPC context. */
    1781         init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
    1782 
    1783         /* create the bind request RPC_HDR_RB */
    1784         init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
    1785 
    1786         /* Start building the frag length. */
    1787         frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
    1788 
    1789         /* Do we need to pad ? */
     1109                                                const DATA_BLOB *auth_info,
     1110                                                DATA_BLOB *blob)
     1111{
     1112        uint16 auth_len = auth_info->length;
     1113        NTSTATUS status;
     1114        union dcerpc_payload u;
     1115        struct dcerpc_ctx_list ctx_list;
     1116
    17901117        if (auth_len) {
    1791                 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
    1792                 if (data_len % 8) {
    1793                         ss_padding_len = 8 - (data_len % 8);
    1794                         phdr_auth->auth_pad_len = ss_padding_len;
    1795                 }
    1796                 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
    1797         }
    1798 
    1799         /* Create the request RPC_HDR */
    1800         init_rpc_hdr(&hdr, pkt_type, DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST, rpc_call_id, frag_len, auth_len);
    1801 
    1802         /* Marshall the RPC header */
    1803         if(!smb_io_rpc_hdr("hdr"   , &hdr, rpc_out, 0)) {
    1804                 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
    1805                 return NT_STATUS_NO_MEMORY;
    1806         }
    1807 
    1808         /* Marshall the bind request data */
    1809         if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
    1810                 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
    1811                 return NT_STATUS_NO_MEMORY;
    1812         }
    1813 
    1814         /*
    1815          * Grow the outgoing buffer to store any auth info.
    1816          */
    1817 
    1818         if(auth_len != 0) {
    1819                 if (ss_padding_len) {
    1820                         char pad[8];
    1821                         memset(pad, '\0', 8);
    1822                         if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
    1823                                 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
    1824                                 return NT_STATUS_NO_MEMORY;
    1825                         }
    1826                 }
    1827 
    1828                 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
    1829                         DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
    1830                         return NT_STATUS_NO_MEMORY;
    1831                 }
    1832 
    1833 
    1834                 if(!prs_append_prs_data( rpc_out, pauth_info)) {
    1835                         DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
    1836                         return NT_STATUS_NO_MEMORY;
    1837                 }
     1118                auth_len -= DCERPC_AUTH_TRAILER_LENGTH;
     1119        }
     1120
     1121        ctx_list.context_id = 0;
     1122        ctx_list.num_transfer_syntaxes = 1;
     1123        ctx_list.abstract_syntax = *abstract;
     1124        ctx_list.transfer_syntaxes = (struct ndr_syntax_id *)discard_const(transfer);
     1125
     1126        u.bind.max_xmit_frag    = RPC_MAX_PDU_FRAG_LEN;
     1127        u.bind.max_recv_frag    = RPC_MAX_PDU_FRAG_LEN;
     1128        u.bind.assoc_group_id   = 0x0;
     1129        u.bind.num_contexts     = 1;
     1130        u.bind.ctx_list         = &ctx_list;
     1131        u.bind.auth_info        = *auth_info;
     1132
     1133        status = dcerpc_push_ncacn_packet(mem_ctx,
     1134                                          ptype,
     1135                                          DCERPC_PFC_FLAG_FIRST |
     1136                                          DCERPC_PFC_FLAG_LAST,
     1137                                          auth_len,
     1138                                          rpc_call_id,
     1139                                          &u,
     1140                                          blob);
     1141        if (!NT_STATUS_IS_OK(status)) {
     1142                DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
     1143                return status;
    18381144        }
    18391145
     
    18451151 ********************************************************************/
    18461152
    1847 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
    1848                                 prs_struct *rpc_out,
    1849                                 uint32 rpc_call_id,
    1850                                 const struct ndr_syntax_id *abstract,
    1851                                 const struct ndr_syntax_id *transfer,
    1852                                 enum pipe_auth_type auth_type,
    1853                                 enum dcerpc_AuthLevel auth_level)
    1854 {
    1855         RPC_HDR_AUTH hdr_auth;
    1856         prs_struct auth_info;
     1153static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx,
     1154                                    struct rpc_pipe_client *cli,
     1155                                    struct pipe_auth_data *auth,
     1156                                    uint32 rpc_call_id,
     1157                                    const struct ndr_syntax_id *abstract,
     1158                                    const struct ndr_syntax_id *transfer,
     1159                                    DATA_BLOB *rpc_out)
     1160{
     1161        DATA_BLOB auth_token = data_blob_null;
     1162        DATA_BLOB auth_info = data_blob_null;
    18571163        NTSTATUS ret = NT_STATUS_OK;
    18581164
    1859         ZERO_STRUCT(hdr_auth);
    1860         if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
    1861                 return NT_STATUS_NO_MEMORY;
    1862 
    1863         switch (auth_type) {
    1864                 case PIPE_AUTH_TYPE_SCHANNEL:
    1865                         ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
    1866                         if (!NT_STATUS_IS_OK(ret)) {
    1867                                 prs_mem_free(&auth_info);
    1868                                 return ret;
    1869                         }
    1870                         break;
    1871 
    1872                 case PIPE_AUTH_TYPE_NTLMSSP:
    1873                         ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
    1874                         if (!NT_STATUS_IS_OK(ret)) {
    1875                                 prs_mem_free(&auth_info);
    1876                                 return ret;
    1877                         }
    1878                         break;
    1879 
    1880                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
    1881                         ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
    1882                         if (!NT_STATUS_IS_OK(ret)) {
    1883                                 prs_mem_free(&auth_info);
    1884                                 return ret;
    1885                         }
    1886                         break;
    1887 
    1888                 case PIPE_AUTH_TYPE_KRB5:
    1889                         ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
    1890                         if (!NT_STATUS_IS_OK(ret)) {
    1891                                 prs_mem_free(&auth_info);
    1892                                 return ret;
    1893                         }
    1894                         break;
    1895 
    1896                 case PIPE_AUTH_TYPE_NONE:
    1897                         break;
    1898 
    1899                 default:
    1900                         /* "Can't" happen. */
    1901                         return NT_STATUS_INVALID_INFO_CLASS;
    1902         }
    1903 
    1904         ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_BIND,
    1905                                                 rpc_out,
    1906                                                 rpc_call_id,
    1907                                                 abstract,
    1908                                                 transfer,
    1909                                                 &hdr_auth,
     1165        switch (auth->auth_type) {
     1166        case DCERPC_AUTH_TYPE_SCHANNEL:
     1167                ret = create_schannel_auth_rpc_bind_req(cli, &auth_token);
     1168                if (!NT_STATUS_IS_OK(ret)) {
     1169                        return ret;
     1170                }
     1171                break;
     1172
     1173        case DCERPC_AUTH_TYPE_NTLMSSP:
     1174                ret = create_ntlmssp_auth_rpc_bind_req(cli, &auth_token);
     1175                if (!NT_STATUS_IS_OK(ret)) {
     1176                        return ret;
     1177                }
     1178                break;
     1179
     1180        case DCERPC_AUTH_TYPE_SPNEGO:
     1181                ret = create_spnego_auth_bind_req(cli, auth, &auth_token);
     1182                if (!NT_STATUS_IS_OK(ret)) {
     1183                        return ret;
     1184                }
     1185                break;
     1186
     1187        case DCERPC_AUTH_TYPE_KRB5:
     1188                ret = create_gssapi_auth_bind_req(mem_ctx, auth, &auth_token);
     1189                if (!NT_STATUS_IS_OK(ret)) {
     1190                        return ret;
     1191                }
     1192                break;
     1193
     1194        case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
     1195                auth_token = data_blob_talloc(mem_ctx,
     1196                                              "NCALRPC_AUTH_TOKEN",
     1197                                              18);
     1198                break;
     1199
     1200        case DCERPC_AUTH_TYPE_NONE:
     1201                break;
     1202
     1203        default:
     1204                /* "Can't" happen. */
     1205                return NT_STATUS_INVALID_INFO_CLASS;
     1206        }
     1207
     1208        if (auth_token.length != 0) {
     1209                ret = dcerpc_push_dcerpc_auth(cli,
     1210                                                auth->auth_type,
     1211                                                auth->auth_level,
     1212                                                0, /* auth_pad_length */
     1213                                                1, /* auth_context_id */
     1214                                                &auth_token,
    19101215                                                &auth_info);
    1911 
    1912         prs_mem_free(&auth_info);
     1216                if (!NT_STATUS_IS_OK(ret)) {
     1217                        return ret;
     1218                }
     1219                data_blob_free(&auth_token);
     1220        }
     1221
     1222        ret = create_bind_or_alt_ctx_internal(mem_ctx,
     1223                                              DCERPC_PKT_BIND,
     1224                                              rpc_call_id,
     1225                                              abstract,
     1226                                              transfer,
     1227                                              &auth_info,
     1228                                              rpc_out);
    19131229        return ret;
    1914 }
    1915 
    1916 /*******************************************************************
    1917  Create and add the NTLMSSP sign/seal auth header and data.
    1918  ********************************************************************/
    1919 
    1920 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
    1921                                         RPC_HDR *phdr,
    1922                                         uint32 ss_padding_len,
    1923                                         prs_struct *outgoing_pdu)
    1924 {
    1925         RPC_HDR_AUTH auth_info;
    1926         NTSTATUS status;
    1927         DATA_BLOB auth_blob = data_blob_null;
    1928         uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
    1929 
    1930         if (!cli->auth->a_u.ntlmssp_state) {
    1931                 return NT_STATUS_INVALID_PARAMETER;
    1932         }
    1933 
    1934         /* Init and marshall the auth header. */
    1935         init_rpc_hdr_auth(&auth_info,
    1936                         map_pipe_auth_type_to_rpc_auth_type(
    1937                                 cli->auth->auth_type),
    1938                         cli->auth->auth_level,
    1939                         ss_padding_len,
    1940                         1 /* context id. */);
    1941 
    1942         if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
    1943                 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
    1944                 data_blob_free(&auth_blob);
    1945                 return NT_STATUS_NO_MEMORY;
    1946         }
    1947 
    1948         switch (cli->auth->auth_level) {
    1949                 case DCERPC_AUTH_LEVEL_PRIVACY:
    1950                         /* Data portion is encrypted. */
    1951                         status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
    1952                                         (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
    1953                                         data_and_pad_len,
    1954                                         (unsigned char *)prs_data_p(outgoing_pdu),
    1955                                         (size_t)prs_offset(outgoing_pdu),
    1956                                         &auth_blob);
    1957                         if (!NT_STATUS_IS_OK(status)) {
    1958                                 data_blob_free(&auth_blob);
    1959                                 return status;
    1960                         }
    1961                         break;
    1962 
    1963                 case DCERPC_AUTH_LEVEL_INTEGRITY:
    1964                         /* Data is signed. */
    1965                         status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
    1966                                         (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
    1967                                         data_and_pad_len,
    1968                                         (unsigned char *)prs_data_p(outgoing_pdu),
    1969                                         (size_t)prs_offset(outgoing_pdu),
    1970                                         &auth_blob);
    1971                         if (!NT_STATUS_IS_OK(status)) {
    1972                                 data_blob_free(&auth_blob);
    1973                                 return status;
    1974                         }
    1975                         break;
    1976 
    1977                 default:
    1978                         /* Can't happen. */
    1979                         smb_panic("bad auth level");
    1980                         /* Notreached. */
    1981                         return NT_STATUS_INVALID_PARAMETER;
    1982         }
    1983 
    1984         /* Finally marshall the blob. */
    1985 
    1986         if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
    1987                 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
    1988                         (unsigned int)NTLMSSP_SIG_SIZE));
    1989                 data_blob_free(&auth_blob);
    1990                 return NT_STATUS_NO_MEMORY;
    1991         }
    1992 
    1993         data_blob_free(&auth_blob);
    1994         return NT_STATUS_OK;
    1995 }
    1996 
    1997 /*******************************************************************
    1998  Create and add the schannel sign/seal auth header and data.
    1999  ********************************************************************/
    2000 
    2001 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
    2002                                         RPC_HDR *phdr,
    2003                                         uint32 ss_padding_len,
    2004                                         prs_struct *outgoing_pdu)
    2005 {
    2006         RPC_HDR_AUTH auth_info;
    2007         struct schannel_state *sas = cli->auth->a_u.schannel_auth;
    2008         char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
    2009         size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
    2010         DATA_BLOB blob;
    2011         NTSTATUS status;
    2012 
    2013         if (!sas) {
    2014                 return NT_STATUS_INVALID_PARAMETER;
    2015         }
    2016 
    2017         /* Init and marshall the auth header. */
    2018         init_rpc_hdr_auth(&auth_info,
    2019                         map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
    2020                         cli->auth->auth_level,
    2021                         ss_padding_len,
    2022                         1 /* context id. */);
    2023 
    2024         if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
    2025                 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
    2026                 return NT_STATUS_NO_MEMORY;
    2027         }
    2028 
    2029         DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
    2030                         sas->seq_num));
    2031 
    2032         switch (cli->auth->auth_level) {
    2033         case DCERPC_AUTH_LEVEL_PRIVACY:
    2034                 status = netsec_outgoing_packet(sas,
    2035                                                 talloc_tos(),
    2036                                                 true,
    2037                                                 (uint8_t *)data_p,
    2038                                                 data_and_pad_len,
    2039                                                 &blob);
    2040                 break;
    2041         case DCERPC_AUTH_LEVEL_INTEGRITY:
    2042                 status = netsec_outgoing_packet(sas,
    2043                                                 talloc_tos(),
    2044                                                 false,
    2045                                                 (uint8_t *)data_p,
    2046                                                 data_and_pad_len,
    2047                                                 &blob);
    2048                 break;
    2049         default:
    2050                 status = NT_STATUS_INTERNAL_ERROR;
    2051                 break;
    2052         }
    2053 
    2054         if (!NT_STATUS_IS_OK(status)) {
    2055                 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
    2056                         nt_errstr(status)));
    2057                 return status;
    2058         }
    2059 
    2060         if (DEBUGLEVEL >= 10) {
    2061                 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
    2062         }
    2063 
    2064         /* Finally marshall the blob. */
    2065         if (!prs_copy_data_in(outgoing_pdu, (const char *)blob.data, blob.length)) {
    2066                 return NT_STATUS_NO_MEMORY;
    2067         }
    2068 
    2069         return NT_STATUS_OK;
    2070 }
    2071 
    2072 /*******************************************************************
    2073  Calculate how much data we're going to send in this packet, also
    2074  work out any sign/seal padding length.
    2075  ********************************************************************/
    2076 
    2077 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
    2078                                         uint32 data_left,
    2079                                         uint16 *p_frag_len,
    2080                                         uint16 *p_auth_len,
    2081                                         uint32 *p_ss_padding)
    2082 {
    2083         uint32 data_space, data_len;
    2084 
    2085 #if 0
    2086         if ((data_left > 0) && (sys_random() % 2)) {
    2087                 data_left = MAX(data_left/2, 1);
    2088         }
    2089 #endif
    2090 
    2091         switch (cli->auth->auth_level) {
    2092                 case DCERPC_AUTH_LEVEL_NONE:
    2093                 case DCERPC_AUTH_LEVEL_CONNECT:
    2094                         data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
    2095                         data_len = MIN(data_space, data_left);
    2096                         *p_ss_padding = 0;
    2097                         *p_auth_len = 0;
    2098                         *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
    2099                         return data_len;
    2100 
    2101                 case DCERPC_AUTH_LEVEL_INTEGRITY:
    2102                 case DCERPC_AUTH_LEVEL_PRIVACY:
    2103                         /* Treat the same for all authenticated rpc requests. */
    2104                         switch(cli->auth->auth_type) {
    2105                                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
    2106                                 case PIPE_AUTH_TYPE_NTLMSSP:
    2107                                         *p_auth_len = NTLMSSP_SIG_SIZE;
    2108                                         break;
    2109                                 case PIPE_AUTH_TYPE_SCHANNEL:
    2110                                         *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
    2111                                         break;
    2112                                 default:
    2113                                         smb_panic("bad auth type");
    2114                                         break;
    2115                         }
    2116 
    2117                         data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
    2118                                                 RPC_HDR_AUTH_LEN - *p_auth_len;
    2119 
    2120                         data_len = MIN(data_space, data_left);
    2121                         *p_ss_padding = 0;
    2122                         if (data_len % 8) {
    2123                                 *p_ss_padding = 8 - (data_len % 8);
    2124                         }
    2125                         *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN +                /* Normal headers. */
    2126                                         data_len + *p_ss_padding +              /* data plus padding. */
    2127                                         RPC_HDR_AUTH_LEN + *p_auth_len;         /* Auth header and auth data. */
    2128                         return data_len;
    2129 
    2130                 default:
    2131                         smb_panic("bad auth level");
    2132                         /* Notreached. */
    2133                         return 0;
    2134         }
    21351230}
    21361231
     
    21471242        uint8_t op_num;
    21481243        uint32_t call_id;
    2149         prs_struct *req_data;
     1244        DATA_BLOB *req_data;
    21501245        uint32_t req_data_sent;
    2151         prs_struct outgoing_frag;
    2152         prs_struct reply_pdu;
     1246        DATA_BLOB rpc_out;
     1247        DATA_BLOB reply_pdu;
    21531248};
    2154 
    2155 static int rpc_api_pipe_req_state_destructor(struct rpc_api_pipe_req_state *s)
    2156 {
    2157         prs_mem_free(&s->outgoing_frag);
    2158         prs_mem_free(&s->reply_pdu);
    2159         return 0;
    2160 }
    21611249
    21621250static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
     
    21691257                                         struct rpc_pipe_client *cli,
    21701258                                         uint8_t op_num,
    2171                                          prs_struct *req_data)
     1259                                         DATA_BLOB *req_data)
    21721260{
    21731261        struct tevent_req *req, *subreq;
     
    21871275        state->req_data_sent = 0;
    21881276        state->call_id = get_rpc_call_id();
    2189 
    2190         if (cli->max_xmit_frag
    2191             < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
     1277        state->reply_pdu = data_blob_null;
     1278        state->rpc_out = data_blob_null;
     1279
     1280        if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
     1281                                        + RPC_MAX_SIGN_SIZE) {
    21921282                /* Server is screwed up ! */
    21931283                status = NT_STATUS_INVALID_PARAMETER;
     
    21951285        }
    21961286
    2197         prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
    2198 
    2199         if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag,
    2200                       state, MARSHALL)) {
    2201                 goto fail;
    2202         }
    2203 
    2204         talloc_set_destructor(state, rpc_api_pipe_req_state_destructor);
    2205 
    22061287        status = prepare_next_frag(state, &is_last_frag);
    22071288        if (!NT_STATUS_IS_OK(status)) {
     
    22111292        if (is_last_frag) {
    22121293                subreq = rpc_api_pipe_send(state, ev, state->cli,
    2213                                            &state->outgoing_frag,
     1294                                           &state->rpc_out,
    22141295                                           DCERPC_PKT_RESPONSE);
    22151296                if (subreq == NULL) {
     
    22181299                tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
    22191300        } else {
    2220                 subreq = rpc_write_send(
    2221                         state, ev, cli->transport,
    2222                         (uint8_t *)prs_data_p(&state->outgoing_frag),
    2223                         prs_offset(&state->outgoing_frag));
     1301                subreq = rpc_write_send(state, ev, cli->transport,
     1302                                        state->rpc_out.data,
     1303                                        state->rpc_out.length);
    22241304                if (subreq == NULL) {
    22251305                        goto fail;
     
    22411321                                  bool *is_last_frag)
    22421322{
    2243         RPC_HDR hdr;
    2244         RPC_HDR_REQ hdr_req;
    2245         uint32_t data_sent_thistime;
    2246         uint16_t auth_len;
    2247         uint16_t frag_len;
     1323        size_t data_sent_thistime;
     1324        size_t auth_len;
     1325        size_t frag_len;
    22481326        uint8_t flags = 0;
    2249         uint32_t ss_padding;
    2250         uint32_t data_left;
    2251         char pad[8] = { 0, };
    2252         NTSTATUS status;
    2253 
    2254         data_left = prs_offset(state->req_data) - state->req_data_sent;
    2255 
    2256         data_sent_thistime = calculate_data_len_tosend(
    2257                 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
     1327        size_t pad_len;
     1328        size_t data_left;
     1329        NTSTATUS status;
     1330        union dcerpc_payload u;
     1331
     1332        data_left = state->req_data->length - state->req_data_sent;
     1333
     1334        status = dcerpc_guess_sizes(state->cli->auth,
     1335                                    DCERPC_REQUEST_LENGTH, data_left,
     1336                                    state->cli->max_xmit_frag,
     1337                                    CLIENT_NDR_PADDING_SIZE,
     1338                                    &data_sent_thistime,
     1339                                    &frag_len, &auth_len, &pad_len);
     1340        if (!NT_STATUS_IS_OK(status)) {
     1341                return status;
     1342        }
    22581343
    22591344        if (state->req_data_sent == 0) {
     
    22651350        }
    22661351
    2267         if (!prs_set_offset(&state->outgoing_frag, 0)) {
     1352        data_blob_free(&state->rpc_out);
     1353
     1354        ZERO_STRUCT(u.request);
     1355
     1356        u.request.alloc_hint    = state->req_data->length;
     1357        u.request.context_id    = 0;
     1358        u.request.opnum         = state->op_num;
     1359
     1360        status = dcerpc_push_ncacn_packet(state,
     1361                                          DCERPC_PKT_REQUEST,
     1362                                          flags,
     1363                                          auth_len,
     1364                                          state->call_id,
     1365                                          &u,
     1366                                          &state->rpc_out);
     1367        if (!NT_STATUS_IS_OK(status)) {
     1368                return status;
     1369        }
     1370
     1371        /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
     1372         * compute it right for requests because the auth trailer is missing
     1373         * at this stage */
     1374        dcerpc_set_frag_length(&state->rpc_out, frag_len);
     1375
     1376        /* Copy in the data. */
     1377        if (!data_blob_append(NULL, &state->rpc_out,
     1378                                state->req_data->data + state->req_data_sent,
     1379                                data_sent_thistime)) {
    22681380                return NT_STATUS_NO_MEMORY;
    22691381        }
    22701382
    2271         /* Create and marshall the header and request header. */
    2272         init_rpc_hdr(&hdr, DCERPC_PKT_REQUEST, flags, state->call_id, frag_len,
    2273                      auth_len);
    2274 
    2275         if (!smb_io_rpc_hdr("hdr    ", &hdr, &state->outgoing_frag, 0)) {
    2276                 return NT_STATUS_NO_MEMORY;
    2277         }
    2278 
    2279         /* Create the rpc request RPC_HDR_REQ */
    2280         init_rpc_hdr_req(&hdr_req, prs_offset(state->req_data),
    2281                          state->op_num);
    2282 
    2283         if (!smb_io_rpc_hdr_req("hdr_req", &hdr_req,
    2284                                 &state->outgoing_frag, 0)) {
    2285                 return NT_STATUS_NO_MEMORY;
    2286         }
    2287 
    2288         /* Copy in the data, plus any ss padding. */
    2289         if (!prs_append_some_prs_data(&state->outgoing_frag,
    2290                                       state->req_data, state->req_data_sent,
    2291                                       data_sent_thistime)) {
    2292                 return NT_STATUS_NO_MEMORY;
    2293         }
    2294 
    2295         /* Copy the sign/seal padding data. */
    2296         if (!prs_copy_data_in(&state->outgoing_frag, pad, ss_padding)) {
    2297                 return NT_STATUS_NO_MEMORY;
    2298         }
    2299 
    2300         /* Generate any auth sign/seal and add the auth footer. */
    2301         switch (state->cli->auth->auth_type) {
    2302         case PIPE_AUTH_TYPE_NONE:
    2303                 status = NT_STATUS_OK;
     1383        switch (state->cli->auth->auth_level) {
     1384        case DCERPC_AUTH_LEVEL_NONE:
     1385        case DCERPC_AUTH_LEVEL_CONNECT:
     1386        case DCERPC_AUTH_LEVEL_PACKET:
    23041387                break;
    2305         case PIPE_AUTH_TYPE_NTLMSSP:
    2306         case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
    2307                 status = add_ntlmssp_auth_footer(state->cli, &hdr, ss_padding,
    2308                                                  &state->outgoing_frag);
    2309                 break;
    2310         case PIPE_AUTH_TYPE_SCHANNEL:
    2311                 status = add_schannel_auth_footer(state->cli, &hdr, ss_padding,
    2312                                                   &state->outgoing_frag);
     1388        case DCERPC_AUTH_LEVEL_INTEGRITY:
     1389        case DCERPC_AUTH_LEVEL_PRIVACY:
     1390                status = dcerpc_add_auth_footer(state->cli->auth, pad_len,
     1391                                                &state->rpc_out);
     1392                if (!NT_STATUS_IS_OK(status)) {
     1393                        return status;
     1394                }
    23131395                break;
    23141396        default:
    2315                 status = NT_STATUS_INVALID_PARAMETER;
    2316                 break;
     1397                return NT_STATUS_INVALID_PARAMETER;
    23171398        }
    23181399
     
    23471428        if (is_last_frag) {
    23481429                subreq = rpc_api_pipe_send(state, state->ev, state->cli,
    2349                                            &state->outgoing_frag,
     1430                                           &state->rpc_out,
    23501431                                           DCERPC_PKT_RESPONSE);
    23511432                if (tevent_req_nomem(subreq, req)) {
     
    23541435                tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
    23551436        } else {
    2356                 subreq = rpc_write_send(
    2357                         state, state->ev,
    2358                         state->cli->transport,
    2359                         (uint8_t *)prs_data_p(&state->outgoing_frag),
    2360                         prs_offset(&state->outgoing_frag));
     1437                subreq = rpc_write_send(state, state->ev,
     1438                                        state->cli->transport,
     1439                                        state->rpc_out.data,
     1440                                        state->rpc_out.length);
    23611441                if (tevent_req_nomem(subreq, req)) {
    23621442                        return;
     
    23751455        NTSTATUS status;
    23761456
    2377         status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu);
     1457        status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
    23781458        TALLOC_FREE(subreq);
    23791459        if (!NT_STATUS_IS_OK(status)) {
     
    23851465
    23861466NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
    2387                                prs_struct *reply_pdu)
     1467                               DATA_BLOB *reply_pdu)
    23881468{
    23891469        struct rpc_api_pipe_req_state *state = tevent_req_data(
     
    23961476                 * none. The rpccli_* caller routines expect this.
    23971477                 */
    2398                 prs_init_empty(reply_pdu, mem_ctx, UNMARSHALL);
     1478                *reply_pdu = data_blob_null;
    23991479                return status;
    24001480        }
    24011481
    2402         *reply_pdu = state->reply_pdu;
    2403         reply_pdu->mem_ctx = mem_ctx;
    2404 
    2405         /*
    2406          * Prevent state->req_pdu from being freed in
    2407          * rpc_api_pipe_req_state_destructor()
    2408          */
    2409         prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
     1482        /* return data to caller and assign it ownership of memory */
     1483        reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
     1484        reply_pdu->length = state->reply_pdu.length;
     1485        state->reply_pdu.length = 0;
    24101486
    24111487        return NT_STATUS_OK;
    24121488}
    2413 
    2414 #if 0
    2415 /****************************************************************************
    2416  Set the handle state.
    2417 ****************************************************************************/
    2418 
    2419 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
    2420                                    const char *pipe_name, uint16 device_state)
    2421 {
    2422         bool state_set = False;
    2423         char param[2];
    2424         uint16 setup[2]; /* only need 2 uint16 setup parameters */
    2425         char *rparam = NULL;
    2426         char *rdata = NULL;
    2427         uint32 rparam_len, rdata_len;
    2428 
    2429         if (pipe_name == NULL)
    2430                 return False;
    2431 
    2432         DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
    2433                  cli->fnum, pipe_name, device_state));
    2434 
    2435         /* create parameters: device state */
    2436         SSVAL(param, 0, device_state);
    2437 
    2438         /* create setup parameters. */
    2439         setup[0] = 0x0001;
    2440         setup[1] = cli->fnum; /* pipe file handle.  got this from an SMBOpenX. */
    2441 
    2442         /* send the data on \PIPE\ */
    2443         if (cli_api_pipe(cli->cli, "\\PIPE\\",
    2444                     setup, 2, 0,                /* setup, length, max */
    2445                     param, 2, 0,                /* param, length, max */
    2446                     NULL, 0, 1024,              /* data, length, max */
    2447                     &rparam, &rparam_len,        /* return param, length */
    2448                     &rdata, &rdata_len))         /* return data, length */
    2449         {
    2450                 DEBUG(5, ("Set Handle state: return OK\n"));
    2451                 state_set = True;
    2452         }
    2453 
    2454         SAFE_FREE(rparam);
    2455         SAFE_FREE(rdata);
    2456 
    2457         return state_set;
    2458 }
    2459 #endif
    24601489
    24611490/****************************************************************************
     
    24631492****************************************************************************/
    24641493
    2465 static bool check_bind_response(RPC_HDR_BA *hdr_ba,
     1494static bool check_bind_response(const struct dcerpc_bind_ack *r,
    24661495                                const struct ndr_syntax_id *transfer)
    24671496{
    2468         if ( hdr_ba->addr.len == 0) {
     1497        struct dcerpc_ack_ctx ctx;
     1498
     1499        if (r->secondary_address_size == 0) {
    24691500                DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
    24701501        }
    24711502
     1503        if (r->num_results < 1 || !r->ctx_list) {
     1504                return false;
     1505        }
     1506
     1507        ctx = r->ctx_list[0];
     1508
    24721509        /* check the transfer syntax */
    2473         if ((hdr_ba->transfer.if_version != transfer->if_version) ||
    2474              (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
     1510        if ((ctx.syntax.if_version != transfer->if_version) ||
     1511             (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
    24751512                DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
    24761513                return False;
    24771514        }
    24781515
    2479         if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
     1516        if (r->num_results != 0x1 || ctx.result != 0) {
    24801517                DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
    2481                           hdr_ba->res.num_results, hdr_ba->res.reason));
     1518                          r->num_results, ctx.reason));
    24821519        }
    24831520
     
    24931530 ********************************************************************/
    24941531
    2495 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
     1532static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
     1533                                struct rpc_pipe_client *cli,
    24961534                                uint32 rpc_call_id,
    2497                                 enum pipe_auth_type auth_type,
     1535                                enum dcerpc_AuthType auth_type,
    24981536                                enum dcerpc_AuthLevel auth_level,
    24991537                                DATA_BLOB *pauth_blob,
    2500                                 prs_struct *rpc_out)
    2501 {
    2502         RPC_HDR hdr;
    2503         RPC_HDR_AUTH hdr_auth;
    2504         uint32 pad = 0;
    2505 
    2506         /* Create the request RPC_HDR */
    2507         init_rpc_hdr(&hdr, DCERPC_PKT_AUTH3, DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST, rpc_call_id,
    2508                      RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
    2509                      pauth_blob->length );
    2510 
    2511         /* Marshall it. */
    2512         if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
    2513                 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
    2514                 return NT_STATUS_NO_MEMORY;
    2515         }
    2516 
    2517         /*
    2518                 I'm puzzled about this - seems to violate the DCE RPC auth rules,
    2519                 about padding - shouldn't this pad to length 8 ? JRA.
    2520         */
    2521 
    2522         /* 4 bytes padding. */
    2523         if (!prs_uint32("pad", rpc_out, 0, &pad)) {
    2524                 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
    2525                 return NT_STATUS_NO_MEMORY;
    2526         }
    2527 
    2528         /* Create the request RPC_HDR_AUTHA */
    2529         init_rpc_hdr_auth(&hdr_auth,
    2530                         map_pipe_auth_type_to_rpc_auth_type(auth_type),
    2531                         auth_level, 0, 1);
    2532 
    2533         if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
    2534                 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
    2535                 return NT_STATUS_NO_MEMORY;
    2536         }
    2537 
    2538         /*
    2539          * Append the auth data to the outgoing buffer.
    2540          */
    2541 
    2542         if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
    2543                 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
    2544                 return NT_STATUS_NO_MEMORY;
     1538                                DATA_BLOB *rpc_out)
     1539{
     1540        NTSTATUS status;
     1541        union dcerpc_payload u;
     1542
     1543        u.auth3._pad = 0;
     1544
     1545        status = dcerpc_push_dcerpc_auth(mem_ctx,
     1546                                         auth_type,
     1547                                         auth_level,
     1548                                         0, /* auth_pad_length */
     1549                                         1, /* auth_context_id */
     1550                                         pauth_blob,
     1551                                         &u.auth3.auth_info);
     1552        if (!NT_STATUS_IS_OK(status)) {
     1553                return status;
     1554        }
     1555
     1556        status = dcerpc_push_ncacn_packet(mem_ctx,
     1557                                          DCERPC_PKT_AUTH3,
     1558                                          DCERPC_PFC_FLAG_FIRST |
     1559                                          DCERPC_PFC_FLAG_LAST,
     1560                                          pauth_blob->length,
     1561                                          rpc_call_id,
     1562                                          &u,
     1563                                          rpc_out);
     1564        data_blob_free(&u.auth3.auth_info);
     1565        if (!NT_STATUS_IS_OK(status)) {
     1566                DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
     1567                return status;
    25451568        }
    25461569
     
    25531576 ********************************************************************/
    25541577
    2555 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
     1578static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
     1579                                        enum dcerpc_AuthType auth_type,
     1580                                        enum dcerpc_AuthLevel auth_level,
     1581                                        uint32 rpc_call_id,
    25561582                                        const struct ndr_syntax_id *abstract,
    25571583                                        const struct ndr_syntax_id *transfer,
    2558                                         enum dcerpc_AuthLevel auth_level,
    25591584                                        const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
    2560                                         prs_struct *rpc_out)
    2561 {
    2562         RPC_HDR_AUTH hdr_auth;
    2563         prs_struct auth_info;
    2564         NTSTATUS ret = NT_STATUS_OK;
    2565 
    2566         ZERO_STRUCT(hdr_auth);
    2567         if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
    2568                 return NT_STATUS_NO_MEMORY;
    2569 
    2570         /* We may change the pad length before marshalling. */
    2571         init_rpc_hdr_auth(&hdr_auth, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1);
    2572 
    2573         if (pauth_blob->length) {
    2574                 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
    2575                         prs_mem_free(&auth_info);
    2576                         return NT_STATUS_NO_MEMORY;
    2577                 }
    2578         }
    2579 
    2580         ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_ALTER,
    2581                                                 rpc_out,
    2582                                                 rpc_call_id,
    2583                                                 abstract,
    2584                                                 transfer,
    2585                                                 &hdr_auth,
    2586                                                 &auth_info);
    2587         prs_mem_free(&auth_info);
    2588         return ret;
     1585                                        DATA_BLOB *rpc_out)
     1586{
     1587        DATA_BLOB auth_info;
     1588        NTSTATUS status;
     1589
     1590        status = dcerpc_push_dcerpc_auth(mem_ctx,
     1591                                         auth_type,
     1592                                         auth_level,
     1593                                         0, /* auth_pad_length */
     1594                                         1, /* auth_context_id */
     1595                                         pauth_blob,
     1596                                         &auth_info);
     1597        if (!NT_STATUS_IS_OK(status)) {
     1598                return status;
     1599        }
     1600
     1601        status = create_bind_or_alt_ctx_internal(mem_ctx,
     1602                                                 DCERPC_PKT_ALTER,
     1603                                                 rpc_call_id,
     1604                                                 abstract,
     1605                                                 transfer,
     1606                                                 &auth_info,
     1607                                                 rpc_out);
     1608        data_blob_free(&auth_info);
     1609        return status;
    25891610}
    25901611
     
    25961617        struct event_context *ev;
    25971618        struct rpc_pipe_client *cli;
    2598         prs_struct rpc_out;
     1619        DATA_BLOB rpc_out;
     1620        bool auth3;
    25991621        uint32_t rpc_call_id;
    26001622};
    26011623
    2602 static int rpc_pipe_bind_state_destructor(struct rpc_pipe_bind_state *state)
    2603 {
    2604         prs_mem_free(&state->rpc_out);
    2605         return 0;
    2606 }
    2607 
    26081624static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
    2609 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
    2610                                            struct rpc_pipe_bind_state *state,
    2611                                            struct rpc_hdr_info *phdr,
    2612                                            prs_struct *reply_pdu);
    2613 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
    2614 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
    2615                                                     struct rpc_pipe_bind_state *state,
    2616                                                     struct rpc_hdr_info *phdr,
    2617                                                     prs_struct *reply_pdu);
    2618 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
     1625static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
     1626                                   struct rpc_pipe_bind_state *state,
     1627                                   DATA_BLOB *credentials);
     1628static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
     1629                                     struct rpc_pipe_bind_state *state,
     1630                                     DATA_BLOB *credentials);
    26191631
    26201632struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
    26211633                                      struct event_context *ev,
    26221634                                      struct rpc_pipe_client *cli,
    2623                                       struct cli_pipe_auth_data *auth)
     1635                                      struct pipe_auth_data *auth)
    26241636{
    26251637        struct tevent_req *req, *subreq;
     
    26411653        state->rpc_call_id = get_rpc_call_id();
    26421654
    2643         prs_init_empty(&state->rpc_out, state, MARSHALL);
    2644         talloc_set_destructor(state, rpc_pipe_bind_state_destructor);
    2645 
    26461655        cli->auth = talloc_move(cli, &auth);
    26471656
    26481657        /* Marshall the outgoing data. */
    2649         status = create_rpc_bind_req(cli, &state->rpc_out,
     1658        status = create_rpc_bind_req(state, cli,
     1659                                     cli->auth,
    26501660                                     state->rpc_call_id,
    26511661                                     &cli->abstract_syntax,
    26521662                                     &cli->transfer_syntax,
    2653                                      cli->auth->auth_type,
    2654                                      cli->auth->auth_level);
     1663                                     &state->rpc_out);
    26551664
    26561665        if (!NT_STATUS_IS_OK(status)) {
     
    26801689        struct rpc_pipe_bind_state *state = tevent_req_data(
    26811690                req, struct rpc_pipe_bind_state);
    2682         prs_struct reply_pdu;
    2683         struct rpc_hdr_info hdr;
    2684         struct rpc_hdr_ba_info hdr_ba;
    2685         NTSTATUS status;
    2686 
    2687         status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
     1691        struct pipe_auth_data *pauth = state->cli->auth;
     1692        struct auth_ntlmssp_state *ntlmssp_ctx;
     1693        struct spnego_context *spnego_ctx;
     1694        struct gse_context *gse_ctx;
     1695        struct ncacn_packet *pkt = NULL;
     1696        struct dcerpc_auth auth;
     1697        DATA_BLOB auth_token = data_blob_null;
     1698        NTSTATUS status;
     1699
     1700        status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
    26881701        TALLOC_FREE(subreq);
    26891702        if (!NT_STATUS_IS_OK(status)) {
     
    26951708        }
    26961709
    2697         /* Unmarshall the RPC header */
    2698         if (!smb_io_rpc_hdr("hdr", &hdr, &reply_pdu, 0)) {
    2699                 DEBUG(0, ("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
    2700                 prs_mem_free(&reply_pdu);
     1710        if (state->auth3) {
     1711                tevent_req_done(req);
     1712                return;
     1713        }
     1714
     1715        if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
     1716                DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
    27011717                tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
    27021718                return;
    27031719        }
    27041720
    2705         if (!smb_io_rpc_hdr_ba("", &hdr_ba, &reply_pdu, 0)) {
    2706                 DEBUG(0, ("rpc_pipe_bind: Failed to unmarshall "
    2707                           "RPC_HDR_BA.\n"));
    2708                 prs_mem_free(&reply_pdu);
    2709                 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
    2710                 return;
    2711         }
    2712 
    2713         if (!check_bind_response(&hdr_ba, &state->cli->transfer_syntax)) {
    2714                 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
    2715                 prs_mem_free(&reply_pdu);
    2716                 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
    2717                 return;
    2718         }
    2719 
    2720         state->cli->max_xmit_frag = hdr_ba.bba.max_tsize;
    2721         state->cli->max_recv_frag = hdr_ba.bba.max_rsize;
     1721        state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
     1722        state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
     1723
     1724        switch(pauth->auth_type) {
     1725
     1726        case DCERPC_AUTH_TYPE_NONE:
     1727        case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
     1728        case DCERPC_AUTH_TYPE_SCHANNEL:
     1729                /* Bind complete. */
     1730                tevent_req_done(req);
     1731                return;
     1732
     1733        case DCERPC_AUTH_TYPE_NTLMSSP:
     1734        case DCERPC_AUTH_TYPE_SPNEGO:
     1735        case DCERPC_AUTH_TYPE_KRB5:
     1736                /* Paranoid lenght checks */
     1737                if (pkt->frag_length < DCERPC_AUTH_TRAILER_LENGTH
     1738                                                + pkt->auth_length) {
     1739                        tevent_req_nterror(req,
     1740                                        NT_STATUS_INFO_LENGTH_MISMATCH);
     1741                        return;
     1742                }
     1743                /* get auth credentials */
     1744                status = dcerpc_pull_dcerpc_auth(talloc_tos(),
     1745                                                 &pkt->u.bind_ack.auth_info,
     1746                                                 &auth, false);
     1747                if (!NT_STATUS_IS_OK(status)) {
     1748                        DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
     1749                                  nt_errstr(status)));
     1750                        tevent_req_nterror(req, status);
     1751                        return;
     1752                }
     1753                break;
     1754
     1755        default:
     1756                goto err_out;
     1757        }
    27221758
    27231759        /*
     
    27251761         */
    27261762
    2727         switch(state->cli->auth->auth_type) {
    2728 
    2729         case PIPE_AUTH_TYPE_NONE:
    2730         case PIPE_AUTH_TYPE_SCHANNEL:
     1763        switch(pauth->auth_type) {
     1764
     1765        case DCERPC_AUTH_TYPE_NONE:
     1766        case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
     1767        case DCERPC_AUTH_TYPE_SCHANNEL:
    27311768                /* Bind complete. */
    2732                 prs_mem_free(&reply_pdu);
    27331769                tevent_req_done(req);
    2734                 break;
    2735 
    2736         case PIPE_AUTH_TYPE_NTLMSSP:
    2737                 /* Need to send AUTH3 packet - no reply. */
    2738                 status = rpc_finish_auth3_bind_send(req, state, &hdr,
    2739                                                     &reply_pdu);
    2740                 prs_mem_free(&reply_pdu);
    2741                 if (!NT_STATUS_IS_OK(status)) {
    2742                         tevent_req_nterror(req, status);
     1770                return;
     1771
     1772        case DCERPC_AUTH_TYPE_NTLMSSP:
     1773                ntlmssp_ctx = talloc_get_type_abort(pauth->auth_ctx,
     1774                                                    struct auth_ntlmssp_state);
     1775                status = auth_ntlmssp_update(ntlmssp_ctx,
     1776                                             auth.credentials, &auth_token);
     1777                if (NT_STATUS_EQUAL(status,
     1778                                    NT_STATUS_MORE_PROCESSING_REQUIRED)) {
     1779                        status = rpc_bind_next_send(req, state,
     1780                                                        &auth_token);
     1781                } else if (NT_STATUS_IS_OK(status)) {
     1782                        status = rpc_bind_finish_send(req, state,
     1783                                                        &auth_token);
    27431784                }
    27441785                break;
    27451786
    2746         case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
    2747                 /* Need to send alter context request and reply. */
    2748                 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, &hdr,
    2749                                                              &reply_pdu);
    2750                 prs_mem_free(&reply_pdu);
     1787        case DCERPC_AUTH_TYPE_SPNEGO:
     1788                spnego_ctx = talloc_get_type_abort(pauth->auth_ctx,
     1789                                                   struct spnego_context);
     1790                status = spnego_get_client_auth_token(state,
     1791                                                spnego_ctx,
     1792                                                &auth.credentials,
     1793                                                &auth_token);
    27511794                if (!NT_STATUS_IS_OK(status)) {
    2752                         tevent_req_nterror(req, status);
     1795                        break;
     1796                }
     1797                if (auth_token.length == 0) {
     1798                        /* Bind complete. */
     1799                        tevent_req_done(req);
     1800                        return;
     1801                }
     1802                if (spnego_require_more_processing(spnego_ctx)) {
     1803                        status = rpc_bind_next_send(req, state,
     1804                                                        &auth_token);
     1805                } else {
     1806                        status = rpc_bind_finish_send(req, state,
     1807                                                        &auth_token);
    27531808                }
    27541809                break;
    27551810
    2756         case PIPE_AUTH_TYPE_KRB5:
    2757                 /* */
     1811        case DCERPC_AUTH_TYPE_KRB5:
     1812                gse_ctx = talloc_get_type_abort(pauth->auth_ctx,
     1813                                                struct gse_context);
     1814                status = gse_get_client_auth_token(state,
     1815                                                   gse_ctx,
     1816                                                   &auth.credentials,
     1817                                                   &auth_token);
     1818                if (!NT_STATUS_IS_OK(status)) {
     1819                        break;
     1820                }
     1821
     1822                if (gse_require_more_processing(gse_ctx)) {
     1823                        status = rpc_bind_next_send(req, state, &auth_token);
     1824                } else {
     1825                        status = rpc_bind_finish_send(req, state, &auth_token);
     1826                }
     1827                break;
    27581828
    27591829        default:
    2760                 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
    2761                          (unsigned int)state->cli->auth->auth_type));
    2762                 prs_mem_free(&reply_pdu);
    2763                 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
    2764         }
    2765 }
    2766 
    2767 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
    2768                                            struct rpc_pipe_bind_state *state,
    2769                                            struct rpc_hdr_info *phdr,
    2770                                            prs_struct *reply_pdu)
    2771 {
    2772         DATA_BLOB server_response = data_blob_null;
    2773         DATA_BLOB client_reply = data_blob_null;
    2774         struct rpc_hdr_auth_info hdr_auth;
     1830                goto err_out;
     1831        }
     1832
     1833        if (!NT_STATUS_IS_OK(status)) {
     1834                tevent_req_nterror(req, status);
     1835        }
     1836        return;
     1837
     1838err_out:
     1839        DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
     1840                 (unsigned int)state->cli->auth->auth_type));
     1841        tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
     1842}
     1843
     1844static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
     1845                                   struct rpc_pipe_bind_state *state,
     1846                                   DATA_BLOB *auth_token)
     1847{
     1848        struct pipe_auth_data *auth = state->cli->auth;
    27751849        struct tevent_req *subreq;
    27761850        NTSTATUS status;
    27771851
    2778         if ((phdr->auth_len == 0)
    2779             || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
    2780                 return NT_STATUS_INVALID_PARAMETER;
    2781         }
    2782 
    2783         if (!prs_set_offset(
    2784                     reply_pdu,
    2785                     phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
    2786                 return NT_STATUS_INVALID_PARAMETER;
    2787         }
    2788 
    2789         if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
    2790                 return NT_STATUS_INVALID_PARAMETER;
    2791         }
    2792 
    2793         /* TODO - check auth_type/auth_level match. */
    2794 
    2795         server_response = data_blob_talloc(talloc_tos(), NULL, phdr->auth_len);
    2796         prs_copy_data_out((char *)server_response.data, reply_pdu,
    2797                           phdr->auth_len);
    2798 
    2799         status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
    2800                                 server_response, &client_reply);
    2801 
    2802         if (!NT_STATUS_IS_OK(status)) {
    2803                 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
    2804                           "blob failed: %s.\n", nt_errstr(status)));
    2805                 return status;
    2806         }
    2807 
    2808         prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL);
    2809 
    2810         status = create_rpc_bind_auth3(state->cli, state->rpc_call_id,
    2811                                        state->cli->auth->auth_type,
    2812                                        state->cli->auth->auth_level,
    2813                                        &client_reply, &state->rpc_out);
    2814         data_blob_free(&client_reply);
    2815 
    2816         if (!NT_STATUS_IS_OK(status)) {
    2817                 return status;
    2818         }
    2819 
    2820         subreq = rpc_write_send(state, state->ev, state->cli->transport,
    2821                                 (uint8_t *)prs_data_p(&state->rpc_out),
    2822                                 prs_offset(&state->rpc_out));
    2823         if (subreq == NULL) {
    2824                 return NT_STATUS_NO_MEMORY;
    2825         }
    2826         tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
    2827         return NT_STATUS_OK;
    2828 }
    2829 
    2830 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
    2831 {
    2832         struct tevent_req *req = tevent_req_callback_data(
    2833                 subreq, struct tevent_req);
    2834         NTSTATUS status;
    2835 
    2836         status = rpc_write_recv(subreq);
    2837         TALLOC_FREE(subreq);
    2838         if (!NT_STATUS_IS_OK(status)) {
    2839                 tevent_req_nterror(req, status);
    2840                 return;
    2841         }
    2842         tevent_req_done(req);
    2843 }
    2844 
    2845 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
    2846                                                     struct rpc_pipe_bind_state *state,
    2847                                                     struct rpc_hdr_info *phdr,
    2848                                                     prs_struct *reply_pdu)
    2849 {
    2850         DATA_BLOB server_spnego_response = data_blob_null;
    2851         DATA_BLOB server_ntlm_response = data_blob_null;
    2852         DATA_BLOB client_reply = data_blob_null;
    2853         DATA_BLOB tmp_blob = data_blob_null;
    2854         RPC_HDR_AUTH hdr_auth;
    2855         struct tevent_req *subreq;
    2856         NTSTATUS status;
    2857 
    2858         if ((phdr->auth_len == 0)
    2859             || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
    2860                 return NT_STATUS_INVALID_PARAMETER;
    2861         }
    2862 
    2863         /* Process the returned NTLMSSP blob first. */
    2864         if (!prs_set_offset(
    2865                     reply_pdu,
    2866                     phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
    2867                 return NT_STATUS_INVALID_PARAMETER;
    2868         }
    2869 
    2870         if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
    2871                 return NT_STATUS_INVALID_PARAMETER;
    2872         }
    2873 
    2874         server_spnego_response = data_blob(NULL, phdr->auth_len);
    2875         prs_copy_data_out((char *)server_spnego_response.data,
    2876                           reply_pdu, phdr->auth_len);
    2877 
    2878         /*
    2879          * The server might give us back two challenges - tmp_blob is for the
    2880          * second.
    2881          */
    2882         if (!spnego_parse_challenge(server_spnego_response,
    2883                                     &server_ntlm_response, &tmp_blob)) {
    2884                 data_blob_free(&server_spnego_response);
    2885                 data_blob_free(&server_ntlm_response);
    2886                 data_blob_free(&tmp_blob);
    2887                 return NT_STATUS_INVALID_PARAMETER;
    2888         }
    2889 
    2890         /* We're finished with the server spnego response and the tmp_blob. */
    2891         data_blob_free(&server_spnego_response);
    2892         data_blob_free(&tmp_blob);
    2893 
    2894         status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
    2895                                 server_ntlm_response, &client_reply);
    2896 
    2897         /* Finished with the server_ntlm response */
    2898         data_blob_free(&server_ntlm_response);
    2899 
    2900         if (!NT_STATUS_IS_OK(status)) {
    2901                 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
    2902                           "using server blob failed.\n"));
    2903                 data_blob_free(&client_reply);
    2904                 return status;
    2905         }
    2906 
    2907         /* SPNEGO wrap the client reply. */
    2908         tmp_blob = spnego_gen_auth(client_reply);
    2909         data_blob_free(&client_reply);
    2910         client_reply = tmp_blob;
    2911         tmp_blob = data_blob_null;
    2912 
    29131852        /* Now prepare the alter context pdu. */
    2914         prs_init_empty(&state->rpc_out, state, MARSHALL);
    2915 
    2916         status = create_rpc_alter_context(state->rpc_call_id,
     1853        data_blob_free(&state->rpc_out);
     1854
     1855        status = create_rpc_alter_context(state,
     1856                                          auth->auth_type,
     1857                                          auth->auth_level,
     1858                                          state->rpc_call_id,
    29171859                                          &state->cli->abstract_syntax,
    29181860                                          &state->cli->transfer_syntax,
    2919                                           state->cli->auth->auth_level,
    2920                                           &client_reply,
     1861                                          auth_token,
    29211862                                          &state->rpc_out);
    2922         data_blob_free(&client_reply);
    2923 
    29241863        if (!NT_STATUS_IS_OK(status)) {
    29251864                return status;
     
    29311870                return NT_STATUS_NO_MEMORY;
    29321871        }
    2933         tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
     1872        tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
    29341873        return NT_STATUS_OK;
    29351874}
    29361875
    2937 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
    2938 {
    2939         struct tevent_req *req = tevent_req_callback_data(
    2940                 subreq, struct tevent_req);
    2941         struct rpc_pipe_bind_state *state = tevent_req_data(
    2942                 req, struct rpc_pipe_bind_state);
    2943         DATA_BLOB server_spnego_response = data_blob_null;
    2944         DATA_BLOB tmp_blob = data_blob_null;
    2945         prs_struct reply_pdu;
    2946         struct rpc_hdr_info hdr;
    2947         struct rpc_hdr_auth_info hdr_auth;
    2948         NTSTATUS status;
    2949 
    2950         status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
    2951         TALLOC_FREE(subreq);
    2952         if (!NT_STATUS_IS_OK(status)) {
    2953                 tevent_req_nterror(req, status);
    2954                 return;
    2955         }
    2956 
    2957         /* Get the auth blob from the reply. */
    2958         if (!smb_io_rpc_hdr("rpc_hdr   ", &hdr, &reply_pdu, 0)) {
    2959                 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: Failed to "
    2960                           "unmarshall RPC_HDR.\n"));
    2961                 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
    2962                 return;
    2963         }
    2964 
    2965         if (!prs_set_offset(
    2966                     &reply_pdu,
    2967                     hdr.frag_len - hdr.auth_len - RPC_HDR_AUTH_LEN)) {
    2968                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
    2969                 return;
    2970         }
    2971 
    2972         if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) {
    2973                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
    2974                 return;
    2975         }
    2976 
    2977         server_spnego_response = data_blob(NULL, hdr.auth_len);
    2978         prs_copy_data_out((char *)server_spnego_response.data, &reply_pdu,
    2979                           hdr.auth_len);
    2980 
    2981         /* Check we got a valid auth response. */
    2982         if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK,
    2983                                         OID_NTLMSSP, &tmp_blob)) {
    2984                 data_blob_free(&server_spnego_response);
    2985                 data_blob_free(&tmp_blob);
    2986                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
    2987                 return;
    2988         }
    2989 
    2990         data_blob_free(&server_spnego_response);
    2991         data_blob_free(&tmp_blob);
    2992 
    2993         DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
    2994                  "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
    2995         tevent_req_done(req);
     1876static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
     1877                                     struct rpc_pipe_bind_state *state,
     1878                                     DATA_BLOB *auth_token)
     1879{
     1880        struct pipe_auth_data *auth = state->cli->auth;
     1881        struct tevent_req *subreq;
     1882        NTSTATUS status;
     1883
     1884        state->auth3 = true;
     1885
     1886        /* Now prepare the auth3 context pdu. */
     1887        data_blob_free(&state->rpc_out);
     1888
     1889        status = create_rpc_bind_auth3(state, state->cli,
     1890                                        state->rpc_call_id,
     1891                                        auth->auth_type,
     1892                                        auth->auth_level,
     1893                                        auth_token,
     1894                                        &state->rpc_out);
     1895        if (!NT_STATUS_IS_OK(status)) {
     1896                return status;
     1897        }
     1898
     1899        subreq = rpc_api_pipe_send(state, state->ev, state->cli,
     1900                                   &state->rpc_out, DCERPC_PKT_AUTH3);
     1901        if (subreq == NULL) {
     1902                return NT_STATUS_NO_MEMORY;
     1903        }
     1904        tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
     1905        return NT_STATUS_OK;
    29961906}
    29971907
     
    30021912
    30031913NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
    3004                        struct cli_pipe_auth_data *auth)
     1914                       struct pipe_auth_data *auth)
    30051915{
    30061916        TALLOC_CTX *frame = talloc_stackframe();
     
    30681978}
    30691979
     1980struct rpccli_bh_state {
     1981        struct rpc_pipe_client *rpc_cli;
     1982};
     1983
     1984static bool rpccli_bh_is_connected(struct dcerpc_binding_handle *h)
     1985{
     1986        struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
     1987                                     struct rpccli_bh_state);
     1988
     1989        return rpccli_is_connected(hs->rpc_cli);
     1990}
     1991
     1992static uint32_t rpccli_bh_set_timeout(struct dcerpc_binding_handle *h,
     1993                                      uint32_t timeout)
     1994{
     1995        struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
     1996                                     struct rpccli_bh_state);
     1997
     1998        return rpccli_set_timeout(hs->rpc_cli, timeout);
     1999}
     2000
     2001struct rpccli_bh_raw_call_state {
     2002        DATA_BLOB in_data;
     2003        DATA_BLOB out_data;
     2004        uint32_t out_flags;
     2005};
     2006
     2007static void rpccli_bh_raw_call_done(struct tevent_req *subreq);
     2008
     2009static struct tevent_req *rpccli_bh_raw_call_send(TALLOC_CTX *mem_ctx,
     2010                                                  struct tevent_context *ev,
     2011                                                  struct dcerpc_binding_handle *h,
     2012                                                  const struct GUID *object,
     2013                                                  uint32_t opnum,
     2014                                                  uint32_t in_flags,
     2015                                                  const uint8_t *in_data,
     2016                                                  size_t in_length)
     2017{
     2018        struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
     2019                                     struct rpccli_bh_state);
     2020        struct tevent_req *req;
     2021        struct rpccli_bh_raw_call_state *state;
     2022        bool ok;
     2023        struct tevent_req *subreq;
     2024
     2025        req = tevent_req_create(mem_ctx, &state,
     2026                                struct rpccli_bh_raw_call_state);
     2027        if (req == NULL) {
     2028                return NULL;
     2029        }
     2030        state->in_data.data = discard_const_p(uint8_t, in_data);
     2031        state->in_data.length = in_length;
     2032
     2033        ok = rpccli_bh_is_connected(h);
     2034        if (!ok) {
     2035                tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION);
     2036                return tevent_req_post(req, ev);
     2037        }
     2038
     2039        subreq = rpc_api_pipe_req_send(state, ev, hs->rpc_cli,
     2040                                       opnum, &state->in_data);
     2041        if (tevent_req_nomem(subreq, req)) {
     2042                return tevent_req_post(req, ev);
     2043        }
     2044        tevent_req_set_callback(subreq, rpccli_bh_raw_call_done, req);
     2045
     2046        return req;
     2047}
     2048
     2049static void rpccli_bh_raw_call_done(struct tevent_req *subreq)
     2050{
     2051        struct tevent_req *req =
     2052                tevent_req_callback_data(subreq,
     2053                struct tevent_req);
     2054        struct rpccli_bh_raw_call_state *state =
     2055                tevent_req_data(req,
     2056                struct rpccli_bh_raw_call_state);
     2057        NTSTATUS status;
     2058
     2059        state->out_flags = 0;
     2060
     2061        /* TODO: support bigendian responses */
     2062
     2063        status = rpc_api_pipe_req_recv(subreq, state, &state->out_data);
     2064        TALLOC_FREE(subreq);
     2065        if (!NT_STATUS_IS_OK(status)) {
     2066                tevent_req_nterror(req, status);
     2067                return;
     2068        }
     2069
     2070        tevent_req_done(req);
     2071}
     2072
     2073static NTSTATUS rpccli_bh_raw_call_recv(struct tevent_req *req,
     2074                                        TALLOC_CTX *mem_ctx,
     2075                                        uint8_t **out_data,
     2076                                        size_t *out_length,
     2077                                        uint32_t *out_flags)
     2078{
     2079        struct rpccli_bh_raw_call_state *state =
     2080                tevent_req_data(req,
     2081                struct rpccli_bh_raw_call_state);
     2082        NTSTATUS status;
     2083
     2084        if (tevent_req_is_nterror(req, &status)) {
     2085                tevent_req_received(req);
     2086                return status;
     2087        }
     2088
     2089        *out_data = talloc_move(mem_ctx, &state->out_data.data);
     2090        *out_length = state->out_data.length;
     2091        *out_flags = state->out_flags;
     2092        tevent_req_received(req);
     2093        return NT_STATUS_OK;
     2094}
     2095
     2096struct rpccli_bh_disconnect_state {
     2097        uint8_t _dummy;
     2098};
     2099
     2100static struct tevent_req *rpccli_bh_disconnect_send(TALLOC_CTX *mem_ctx,
     2101                                                struct tevent_context *ev,
     2102                                                struct dcerpc_binding_handle *h)
     2103{
     2104        struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
     2105                                     struct rpccli_bh_state);
     2106        struct tevent_req *req;
     2107        struct rpccli_bh_disconnect_state *state;
     2108        bool ok;
     2109
     2110        req = tevent_req_create(mem_ctx, &state,
     2111                                struct rpccli_bh_disconnect_state);
     2112        if (req == NULL) {
     2113                return NULL;
     2114        }
     2115
     2116        ok = rpccli_bh_is_connected(h);
     2117        if (!ok) {
     2118                tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION);
     2119                return tevent_req_post(req, ev);
     2120        }
     2121
     2122        /*
     2123         * TODO: do a real async disconnect ...
     2124         *
     2125         * For now the caller needs to free rpc_cli
     2126         */
     2127        hs->rpc_cli = NULL;
     2128
     2129        tevent_req_done(req);
     2130        return tevent_req_post(req, ev);
     2131}
     2132
     2133static NTSTATUS rpccli_bh_disconnect_recv(struct tevent_req *req)
     2134{
     2135        NTSTATUS status;
     2136
     2137        if (tevent_req_is_nterror(req, &status)) {
     2138                tevent_req_received(req);
     2139                return status;
     2140        }
     2141
     2142        tevent_req_received(req);
     2143        return NT_STATUS_OK;
     2144}
     2145
     2146static bool rpccli_bh_ref_alloc(struct dcerpc_binding_handle *h)
     2147{
     2148        return true;
     2149}
     2150
     2151static void rpccli_bh_do_ndr_print(struct dcerpc_binding_handle *h,
     2152                                   int ndr_flags,
     2153                                   const void *_struct_ptr,
     2154                                   const struct ndr_interface_call *call)
     2155{
     2156        void *struct_ptr = discard_const(_struct_ptr);
     2157
     2158        if (DEBUGLEVEL < 10) {
     2159                return;
     2160        }
     2161
     2162        if (ndr_flags & NDR_IN) {
     2163                ndr_print_function_debug(call->ndr_print,
     2164                                         call->name,
     2165                                         ndr_flags,
     2166                                         struct_ptr);
     2167        }
     2168        if (ndr_flags & NDR_OUT) {
     2169                ndr_print_function_debug(call->ndr_print,
     2170                                         call->name,
     2171                                         ndr_flags,
     2172                                         struct_ptr);
     2173        }
     2174}
     2175
     2176static const struct dcerpc_binding_handle_ops rpccli_bh_ops = {
     2177        .name                   = "rpccli",
     2178        .is_connected           = rpccli_bh_is_connected,
     2179        .set_timeout            = rpccli_bh_set_timeout,
     2180        .raw_call_send          = rpccli_bh_raw_call_send,
     2181        .raw_call_recv          = rpccli_bh_raw_call_recv,
     2182        .disconnect_send        = rpccli_bh_disconnect_send,
     2183        .disconnect_recv        = rpccli_bh_disconnect_recv,
     2184
     2185        .ref_alloc              = rpccli_bh_ref_alloc,
     2186        .do_ndr_print           = rpccli_bh_do_ndr_print,
     2187};
     2188
     2189/* initialise a rpc_pipe_client binding handle */
     2190struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c)
     2191{
     2192        struct dcerpc_binding_handle *h;
     2193        struct rpccli_bh_state *hs;
     2194
     2195        h = dcerpc_binding_handle_create(c,
     2196                                         &rpccli_bh_ops,
     2197                                         NULL,
     2198                                         NULL, /* TODO */
     2199                                         &hs,
     2200                                         struct rpccli_bh_state,
     2201                                         __location__);
     2202        if (h == NULL) {
     2203                return NULL;
     2204        }
     2205        hs->rpc_cli = c;
     2206
     2207        return h;
     2208}
     2209
    30702210bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
    30712211{
     2212        struct auth_ntlmssp_state *a = NULL;
    30722213        struct cli_state *cli;
    30732214
    3074         if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
    3075             || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
    3076                 memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16);
     2215        if (rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_NTLMSSP) {
     2216                a = talloc_get_type_abort(rpc_cli->auth->auth_ctx,
     2217                                          struct auth_ntlmssp_state);
     2218        } else if (rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_SPNEGO) {
     2219                struct spnego_context *spnego_ctx;
     2220                enum spnego_mech auth_type;
     2221                void *auth_ctx;
     2222                NTSTATUS status;
     2223
     2224                spnego_ctx = talloc_get_type_abort(rpc_cli->auth->auth_ctx,
     2225                                                   struct spnego_context);
     2226                status = spnego_get_negotiated_mech(spnego_ctx,
     2227                                                    &auth_type, &auth_ctx);
     2228                if (!NT_STATUS_IS_OK(status)) {
     2229                        return false;
     2230                }
     2231
     2232                if (auth_type == SPNEGO_NTLMSSP) {
     2233                        a = talloc_get_type_abort(auth_ctx,
     2234                                                  struct auth_ntlmssp_state);
     2235                }
     2236        }
     2237
     2238        if (a) {
     2239                memcpy(nt_hash, auth_ntlmssp_get_nt_hash(a), 16);
    30772240                return true;
    30782241        }
     
    30862249}
    30872250
    3088 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
    3089                                struct cli_pipe_auth_data **presult)
    3090 {
    3091         struct cli_pipe_auth_data *result;
    3092 
    3093         result = talloc(mem_ctx, struct cli_pipe_auth_data);
     2251NTSTATUS rpccli_ncalrpc_bind_data(TALLOC_CTX *mem_ctx,
     2252                                  struct pipe_auth_data **presult)
     2253{
     2254        struct pipe_auth_data *result;
     2255
     2256        result = talloc(mem_ctx, struct pipe_auth_data);
    30942257        if (result == NULL) {
    30952258                return NT_STATUS_NO_MEMORY;
    30962259        }
    30972260
    3098         result->auth_type = PIPE_AUTH_TYPE_NONE;
    3099         result->auth_level = DCERPC_AUTH_LEVEL_NONE;
     2261        result->auth_type = DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM;
     2262        result->auth_level = DCERPC_AUTH_LEVEL_CONNECT;
    31002263
    31012264        result->user_name = talloc_strdup(result, "");
     
    31102273}
    31112274
    3112 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
    3113 {
    3114         ntlmssp_end(&auth->a_u.ntlmssp_state);
     2275NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
     2276                               struct pipe_auth_data **presult)
     2277{
     2278        struct pipe_auth_data *result;
     2279
     2280        result = talloc(mem_ctx, struct pipe_auth_data);
     2281        if (result == NULL) {
     2282                return NT_STATUS_NO_MEMORY;
     2283        }
     2284
     2285        result->auth_type = DCERPC_AUTH_TYPE_NONE;
     2286        result->auth_level = DCERPC_AUTH_LEVEL_NONE;
     2287
     2288        result->user_name = talloc_strdup(result, "");
     2289        result->domain = talloc_strdup(result, "");
     2290        if ((result->user_name == NULL) || (result->domain == NULL)) {
     2291                TALLOC_FREE(result);
     2292                return NT_STATUS_NO_MEMORY;
     2293        }
     2294
     2295        *presult = result;
     2296        return NT_STATUS_OK;
     2297}
     2298
     2299static int cli_auth_ntlmssp_data_destructor(struct pipe_auth_data *auth)
     2300{
     2301        TALLOC_FREE(auth->auth_ctx);
    31152302        return 0;
    31162303}
    31172304
    31182305static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
    3119                                   enum pipe_auth_type auth_type,
     2306                                  enum dcerpc_AuthType auth_type,
    31202307                                  enum dcerpc_AuthLevel auth_level,
    31212308                                  const char *domain,
    31222309                                  const char *username,
    31232310                                  const char *password,
    3124                                   struct cli_pipe_auth_data **presult)
    3125 {
    3126         struct cli_pipe_auth_data *result;
    3127         NTSTATUS status;
    3128 
    3129         result = talloc(mem_ctx, struct cli_pipe_auth_data);
     2311                                  struct pipe_auth_data **presult)
     2312{
     2313        struct auth_ntlmssp_state *ntlmssp_ctx;
     2314        struct pipe_auth_data *result;
     2315        NTSTATUS status;
     2316
     2317        result = talloc(mem_ctx, struct pipe_auth_data);
    31302318        if (result == NULL) {
    31312319                return NT_STATUS_NO_MEMORY;
     
    31422330        }
    31432331
    3144         status = ntlmssp_client_start(&result->a_u.ntlmssp_state);
     2332        status = auth_ntlmssp_client_start(NULL,
     2333                                      global_myname(),
     2334                                      lp_workgroup(),
     2335                                      lp_client_ntlmv2_auth(),
     2336                                      &ntlmssp_ctx);
    31452337        if (!NT_STATUS_IS_OK(status)) {
    31462338                goto fail;
     
    31492341        talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
    31502342
    3151         status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
     2343        status = auth_ntlmssp_set_username(ntlmssp_ctx, username);
    31522344        if (!NT_STATUS_IS_OK(status)) {
    31532345                goto fail;
    31542346        }
    31552347
    3156         status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
     2348        status = auth_ntlmssp_set_domain(ntlmssp_ctx, domain);
    31572349        if (!NT_STATUS_IS_OK(status)) {
    31582350                goto fail;
    31592351        }
    31602352
    3161         status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
     2353        status = auth_ntlmssp_set_password(ntlmssp_ctx, password);
    31622354        if (!NT_STATUS_IS_OK(status)) {
    31632355                goto fail;
     
    31672359         * Turn off sign+seal to allow selected auth level to turn it back on.
    31682360         */
    3169         result->a_u.ntlmssp_state->neg_flags &=
    3170                 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
     2361        auth_ntlmssp_and_flags(ntlmssp_ctx, ~(NTLMSSP_NEGOTIATE_SIGN |
     2362                                                NTLMSSP_NEGOTIATE_SEAL));
    31712363
    31722364        if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
    3173                 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
     2365                auth_ntlmssp_or_flags(ntlmssp_ctx, NTLMSSP_NEGOTIATE_SIGN);
    31742366        } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
    3175                 result->a_u.ntlmssp_state->neg_flags
    3176                         |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
    3177         }
    3178 
     2367                auth_ntlmssp_or_flags(ntlmssp_ctx, NTLMSSP_NEGOTIATE_SEAL |
     2368                                                     NTLMSSP_NEGOTIATE_SIGN);
     2369        }
     2370
     2371        result->auth_ctx = ntlmssp_ctx;
    31792372        *presult = result;
    31802373        return NT_STATUS_OK;
     
    31882381                                   enum dcerpc_AuthLevel auth_level,
    31892382                                   struct netlogon_creds_CredentialState *creds,
    3190                                    struct cli_pipe_auth_data **presult)
    3191 {
    3192         struct cli_pipe_auth_data *result;
    3193 
    3194         result = talloc(mem_ctx, struct cli_pipe_auth_data);
     2383                                   struct pipe_auth_data **presult)
     2384{
     2385        struct schannel_state *schannel_auth;
     2386        struct pipe_auth_data *result;
     2387
     2388        result = talloc(mem_ctx, struct pipe_auth_data);
    31952389        if (result == NULL) {
    31962390                return NT_STATUS_NO_MEMORY;
    31972391        }
    31982392
    3199         result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
     2393        result->auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
    32002394        result->auth_level = auth_level;
    32012395
     
    32062400        }
    32072401
    3208         result->a_u.schannel_auth = talloc(result, struct schannel_state);
    3209         if (result->a_u.schannel_auth == NULL) {
     2402        schannel_auth = talloc(result, struct schannel_state);
     2403        if (schannel_auth == NULL) {
    32102404                goto fail;
    32112405        }
    32122406
    3213         result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
    3214         result->a_u.schannel_auth->seq_num = 0;
    3215         result->a_u.schannel_auth->initiator = true;
    3216         result->a_u.schannel_auth->creds = netlogon_creds_copy(result, creds);
    3217 
     2407        schannel_auth->state = SCHANNEL_STATE_START;
     2408        schannel_auth->seq_num = 0;
     2409        schannel_auth->initiator = true;
     2410        schannel_auth->creds = netlogon_creds_copy(result, creds);
     2411
     2412        result->auth_ctx = schannel_auth;
    32182413        *presult = result;
    32192414        return NT_STATUS_OK;
     
    32222417        TALLOC_FREE(result);
    32232418        return NT_STATUS_NO_MEMORY;
    3224 }
    3225 
    3226 #ifdef HAVE_KRB5
    3227 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
    3228 {
    3229         data_blob_free(&auth->session_key);
    3230         return 0;
    3231 }
    3232 #endif
    3233 
    3234 static NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
    3235                                    enum dcerpc_AuthLevel auth_level,
    3236                                    const char *service_princ,
    3237                                    const char *username,
    3238                                    const char *password,
    3239                                    struct cli_pipe_auth_data **presult)
    3240 {
    3241 #ifdef HAVE_KRB5
    3242         struct cli_pipe_auth_data *result;
    3243 
    3244         if ((username != NULL) && (password != NULL)) {
    3245                 int ret = kerberos_kinit_password(username, password, 0, NULL);
    3246                 if (ret != 0) {
    3247                         return NT_STATUS_ACCESS_DENIED;
    3248                 }
    3249         }
    3250 
    3251         result = talloc(mem_ctx, struct cli_pipe_auth_data);
    3252         if (result == NULL) {
    3253                 return NT_STATUS_NO_MEMORY;
    3254         }
    3255 
    3256         result->auth_type = PIPE_AUTH_TYPE_KRB5;
    3257         result->auth_level = auth_level;
    3258 
    3259         /*
    3260          * Username / domain need fixing!
    3261          */
    3262         result->user_name = talloc_strdup(result, "");
    3263         result->domain = talloc_strdup(result, "");
    3264         if ((result->user_name == NULL) || (result->domain == NULL)) {
    3265                 goto fail;
    3266         }
    3267 
    3268         result->a_u.kerberos_auth = TALLOC_ZERO_P(
    3269                 result, struct kerberos_auth_struct);
    3270         if (result->a_u.kerberos_auth == NULL) {
    3271                 goto fail;
    3272         }
    3273         talloc_set_destructor(result->a_u.kerberos_auth,
    3274                               cli_auth_kerberos_data_destructor);
    3275 
    3276         result->a_u.kerberos_auth->service_principal = talloc_strdup(
    3277                 result, service_princ);
    3278         if (result->a_u.kerberos_auth->service_principal == NULL) {
    3279                 goto fail;
    3280         }
    3281 
    3282         *presult = result;
    3283         return NT_STATUS_OK;
    3284 
    3285  fail:
    3286         TALLOC_FREE(result);
    3287         return NT_STATUS_NO_MEMORY;
    3288 #else
    3289         return NT_STATUS_NOT_SUPPORTED;
    3290 #endif
    32912419}
    32922420
     
    33112439        result->abstract_syntax = *abstract_syntax;
    33122440        result->transfer_syntax = ndr_transfer_syntax;
    3313         result->dispatch = cli_do_rpc_ndr;
    3314         result->dispatch_send = cli_do_rpc_ndr_send;
    3315         result->dispatch_recv = cli_do_rpc_ndr_recv;
    33162441
    33172442        result->desthost = talloc_strdup(result, host);
     
    33442469
    33452470        result->transport->transport = NCACN_IP_TCP;
     2471
     2472        result->binding_handle = rpccli_bh_create(result);
     2473        if (result->binding_handle == NULL) {
     2474                TALLOC_FREE(result);
     2475                return NT_STATUS_NO_MEMORY;
     2476        }
    33462477
    33472478        *presult = result;
     
    33642495        NTSTATUS status;
    33652496        struct rpc_pipe_client *epm_pipe = NULL;
    3366         struct cli_pipe_auth_data *auth = NULL;
     2497        struct dcerpc_binding_handle *epm_handle = NULL;
     2498        struct pipe_auth_data *auth = NULL;
    33672499        struct dcerpc_binding *map_binding = NULL;
    33682500        struct dcerpc_binding *res_binding = NULL;
     
    33742506        struct epm_twr_p_t towers;
    33752507        TALLOC_CTX *tmp_ctx = talloc_stackframe();
     2508        uint32_t result = 0;
    33762509
    33772510        if (pport == NULL) {
    33782511                status = NT_STATUS_INVALID_PARAMETER;
    33792512                goto done;
     2513        }
     2514
     2515        if (ndr_syntax_id_equal(abstract_syntax,
     2516                                &ndr_table_epmapper.syntax_id)) {
     2517                *pport = 135;
     2518                return NT_STATUS_OK;
    33802519        }
    33812520
     
    33882527                goto done;
    33892528        }
     2529        epm_handle = epm_pipe->binding_handle;
    33902530
    33912531        status = rpccli_anon_bind_data(tmp_ctx, &auth);
     
    34412581        /* ask the endpoint mapper for the port */
    34422582
    3443         status = rpccli_epm_Map(epm_pipe,
     2583        status = dcerpc_epm_Map(epm_handle,
    34442584                                tmp_ctx,
    34452585                                CONST_DISCARD(struct GUID *,
     
    34492589                                max_towers,
    34502590                                &num_towers,
    3451                                 &towers);
    3452 
    3453         if (!NT_STATUS_IS_OK(status)) {
     2591                                &towers,
     2592                                &result);
     2593
     2594        if (!NT_STATUS_IS_OK(status)) {
     2595                goto done;
     2596        }
     2597
     2598        if (result != EPMAPPER_STATUS_OK) {
     2599                status = NT_STATUS_UNSUCCESSFUL;
    34542600                goto done;
    34552601        }
     
    35222668        result->abstract_syntax = *abstract_syntax;
    35232669        result->transfer_syntax = ndr_transfer_syntax;
    3524         result->dispatch = cli_do_rpc_ndr;
    3525         result->dispatch_send = cli_do_rpc_ndr_send;
    3526         result->dispatch_recv = cli_do_rpc_ndr_recv;
    35272670
    35282671        result->desthost = get_myname(result);
     
    35452688        ZERO_STRUCT(addr);
    35462689        addr.sun_family = AF_UNIX;
    3547         strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
     2690        strlcpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
    35482691
    35492692        if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
     
    35612704
    35622705        result->transport->transport = NCALRPC;
     2706
     2707        result->binding_handle = rpccli_bh_create(result);
     2708        if (result->binding_handle == NULL) {
     2709                TALLOC_FREE(result);
     2710                return NT_STATUS_NO_MEMORY;
     2711        }
    35632712
    35642713        *presult = result;
     
    36152764        result->abstract_syntax = *abstract_syntax;
    36162765        result->transfer_syntax = ndr_transfer_syntax;
    3617         result->dispatch = cli_do_rpc_ndr;
    3618         result->dispatch_send = cli_do_rpc_ndr_send;
    3619         result->dispatch_recv = cli_do_rpc_ndr_recv;
    36202766        result->desthost = talloc_strdup(result, cli->desthost);
    36212767        result->srv_name_slash = talloc_asprintf_strupper_m(
     
    36502796        talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
    36512797
    3652         *presult = result;
    3653         return NT_STATUS_OK;
    3654 }
    3655 
    3656 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
    3657                              struct rpc_cli_smbd_conn *conn,
    3658                              const struct ndr_syntax_id *syntax,
    3659                              struct rpc_pipe_client **presult)
    3660 {
    3661         struct rpc_pipe_client *result;
    3662         struct cli_pipe_auth_data *auth;
    3663         NTSTATUS status;
    3664 
    3665         result = talloc(mem_ctx, struct rpc_pipe_client);
    3666         if (result == NULL) {
    3667                 return NT_STATUS_NO_MEMORY;
    3668         }
    3669         result->abstract_syntax = *syntax;
    3670         result->transfer_syntax = ndr_transfer_syntax;
    3671         result->dispatch = cli_do_rpc_ndr;
    3672         result->dispatch_send = cli_do_rpc_ndr_send;
    3673         result->dispatch_recv = cli_do_rpc_ndr_recv;
    3674         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
    3675         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
    3676 
    3677         result->desthost = talloc_strdup(result, global_myname());
    3678         result->srv_name_slash = talloc_asprintf_strupper_m(
    3679                 result, "\\\\%s", global_myname());
    3680         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
     2798        result->binding_handle = rpccli_bh_create(result);
     2799        if (result->binding_handle == NULL) {
    36812800                TALLOC_FREE(result);
    36822801                return NT_STATUS_NO_MEMORY;
    36832802        }
    3684 
    3685         status = rpc_transport_smbd_init(result, conn, syntax,
    3686                                          &result->transport);
    3687         if (!NT_STATUS_IS_OK(status)) {
    3688                 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
    3689                           nt_errstr(status)));
    3690                 TALLOC_FREE(result);
    3691                 return status;
    3692         }
    3693 
    3694         status = rpccli_anon_bind_data(result, &auth);
    3695         if (!NT_STATUS_IS_OK(status)) {
    3696                 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
    3697                           nt_errstr(status)));
    3698                 TALLOC_FREE(result);
    3699                 return status;
    3700         }
    3701 
    3702         status = rpc_pipe_bind(result, auth);
    3703         if (!NT_STATUS_IS_OK(status)) {
    3704                 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
    3705                 TALLOC_FREE(result);
    3706                 return status;
    3707         }
    3708 
    3709         result->transport->transport = NCACN_INTERNAL;
    37102803
    37112804        *presult = result;
     
    37432836{
    37442837        struct rpc_pipe_client *result;
    3745         struct cli_pipe_auth_data *auth;
     2838        struct pipe_auth_data *auth;
    37462839        NTSTATUS status;
    37472840
     
    38202913 ****************************************************************************/
    38212914
    3822 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
    3823                                                    const struct ndr_syntax_id *interface,
    3824                                                    enum dcerpc_transport_t transport,
    3825                                                    enum pipe_auth_type auth_type,
    3826                                                    enum dcerpc_AuthLevel auth_level,
    3827                                                    const char *domain,
    3828                                                    const char *username,
    3829                                                    const char *password,
    3830                                                    struct rpc_pipe_client **presult)
    3831 {
    3832         struct rpc_pipe_client *result;
    3833         struct cli_pipe_auth_data *auth;
    3834         NTSTATUS status;
    3835 
    3836         status = cli_rpc_pipe_open(cli, transport, interface, &result);
    3837         if (!NT_STATUS_IS_OK(status)) {
    3838                 return status;
    3839         }
    3840 
    3841         status = rpccli_ntlmssp_bind_data(
    3842                 result, auth_type, auth_level, domain, username,
    3843                 password, &auth);
    3844         if (!NT_STATUS_IS_OK(status)) {
    3845                 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
    3846                           nt_errstr(status)));
    3847                 goto err;
    3848         }
    3849 
    3850         status = rpc_pipe_bind(result, auth);
    3851         if (!NT_STATUS_IS_OK(status)) {
    3852                 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
    3853                         nt_errstr(status) ));
    3854                 goto err;
    3855         }
    3856 
    3857         DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
    3858                 "machine %s and bound NTLMSSP as user %s\\%s.\n",
    3859                   get_pipe_name_from_syntax(talloc_tos(), interface),
    3860                   cli->desthost, domain, username ));
    3861 
    3862         *presult = result;
    3863         return NT_STATUS_OK;
    3864 
    3865   err:
    3866 
    3867         TALLOC_FREE(result);
    3868         return status;
    3869 }
    3870 
    3871 /****************************************************************************
    3872  External interface.
    3873  Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
    3874  ****************************************************************************/
    3875 
    38762915NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
    38772916                                   const struct ndr_syntax_id *interface,
     
    38832922                                   struct rpc_pipe_client **presult)
    38842923{
    3885         return cli_rpc_pipe_open_ntlmssp_internal(cli,
    3886                                                 interface,
    3887                                                 transport,
    3888                                                 PIPE_AUTH_TYPE_NTLMSSP,
    3889                                                 auth_level,
    3890                                                 domain,
    3891                                                 username,
    3892                                                 password,
    3893                                                 presult);
     2924        struct rpc_pipe_client *result;
     2925        struct pipe_auth_data *auth = NULL;
     2926        enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
     2927        NTSTATUS status;
     2928
     2929        status = cli_rpc_pipe_open(cli, transport, interface, &result);
     2930        if (!NT_STATUS_IS_OK(status)) {
     2931                return status;
     2932        }
     2933
     2934        status = rpccli_ntlmssp_bind_data(result,
     2935                                          auth_type, auth_level,
     2936                                          domain, username, password,
     2937                                          &auth);
     2938        if (!NT_STATUS_IS_OK(status)) {
     2939                DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
     2940                          nt_errstr(status)));
     2941                goto err;
     2942        }
     2943
     2944        status = rpc_pipe_bind(result, auth);
     2945        if (!NT_STATUS_IS_OK(status)) {
     2946                DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
     2947                        nt_errstr(status) ));
     2948                goto err;
     2949        }
     2950
     2951        DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
     2952                "machine %s and bound NTLMSSP as user %s\\%s.\n",
     2953                  get_pipe_name_from_syntax(talloc_tos(), interface),
     2954                  cli->desthost, domain, username ));
     2955
     2956        *presult = result;
     2957        return NT_STATUS_OK;
     2958
     2959  err:
     2960
     2961        TALLOC_FREE(result);
     2962        return status;
    38942963}
    38952964
    38962965/****************************************************************************
    38972966 External interface.
    3898  Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
     2967 Open a named pipe to an SMB server and bind using schannel (bind type 68)
     2968 using session_key. sign and seal.
     2969
     2970 The *pdc will be stolen onto this new pipe
    38992971 ****************************************************************************/
     2972
     2973NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
     2974                                             const struct ndr_syntax_id *interface,
     2975                                             enum dcerpc_transport_t transport,
     2976                                             enum dcerpc_AuthLevel auth_level,
     2977                                             const char *domain,
     2978                                             struct netlogon_creds_CredentialState **pdc,
     2979                                             struct rpc_pipe_client **presult)
     2980{
     2981        struct rpc_pipe_client *result;
     2982        struct pipe_auth_data *auth;
     2983        NTSTATUS status;
     2984
     2985        status = cli_rpc_pipe_open(cli, transport, interface, &result);
     2986        if (!NT_STATUS_IS_OK(status)) {
     2987                return status;
     2988        }
     2989
     2990        status = rpccli_schannel_bind_data(result, domain, auth_level,
     2991                                           *pdc, &auth);
     2992        if (!NT_STATUS_IS_OK(status)) {
     2993                DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
     2994                          nt_errstr(status)));
     2995                TALLOC_FREE(result);
     2996                return status;
     2997        }
     2998
     2999        status = rpc_pipe_bind(result, auth);
     3000        if (!NT_STATUS_IS_OK(status)) {
     3001                DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
     3002                          "cli_rpc_pipe_bind failed with error %s\n",
     3003                          nt_errstr(status) ));
     3004                TALLOC_FREE(result);
     3005                return status;
     3006        }
     3007
     3008        /*
     3009         * The credentials on a new netlogon pipe are the ones we are passed
     3010         * in - copy them over
     3011         */
     3012        result->dc = netlogon_creds_copy(result, *pdc);
     3013        if (result->dc == NULL) {
     3014                TALLOC_FREE(result);
     3015                return NT_STATUS_NO_MEMORY;
     3016        }
     3017
     3018        DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
     3019                  "for domain %s and bound using schannel.\n",
     3020                  get_pipe_name_from_syntax(talloc_tos(), interface),
     3021                  cli->desthost, domain ));
     3022
     3023        *presult = result;
     3024        return NT_STATUS_OK;
     3025}
     3026
     3027/****************************************************************************
     3028 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
     3029 The idea is this can be called with service_princ, username and password all
     3030 NULL so long as the caller has a TGT.
     3031 ****************************************************************************/
     3032
     3033NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
     3034                                const struct ndr_syntax_id *interface,
     3035                                enum dcerpc_transport_t transport,
     3036                                enum dcerpc_AuthLevel auth_level,
     3037                                const char *server,
     3038                                const char *username,
     3039                                const char *password,
     3040                                struct rpc_pipe_client **presult)
     3041{
     3042        struct rpc_pipe_client *result;
     3043        struct pipe_auth_data *auth;
     3044        struct gse_context *gse_ctx;
     3045        NTSTATUS status;
     3046
     3047        status = cli_rpc_pipe_open(cli, transport, interface, &result);
     3048        if (!NT_STATUS_IS_OK(status)) {
     3049                return status;
     3050        }
     3051
     3052        auth = talloc(result, struct pipe_auth_data);
     3053        if (auth == NULL) {
     3054                status = NT_STATUS_NO_MEMORY;
     3055                goto err_out;
     3056        }
     3057        auth->auth_type = DCERPC_AUTH_TYPE_KRB5;
     3058        auth->auth_level = auth_level;
     3059
     3060        if (!username) {
     3061                username = "";
     3062        }
     3063        auth->user_name = talloc_strdup(auth, username);
     3064        if (!auth->user_name) {
     3065                status = NT_STATUS_NO_MEMORY;
     3066                goto err_out;
     3067        }
     3068
     3069        /* Fixme, should we fetch/set the Realm ? */
     3070        auth->domain = talloc_strdup(auth, "");
     3071        if (!auth->domain) {
     3072                status = NT_STATUS_NO_MEMORY;
     3073                goto err_out;
     3074        }
     3075
     3076        status = gse_init_client(auth,
     3077                                 (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY),
     3078                                 (auth_level == DCERPC_AUTH_LEVEL_PRIVACY),
     3079                                 NULL, server, "cifs", username, password,
     3080                                 GSS_C_DCE_STYLE, &gse_ctx);
     3081        if (!NT_STATUS_IS_OK(status)) {
     3082                DEBUG(0, ("gse_init_client returned %s\n",
     3083                          nt_errstr(status)));
     3084                goto err_out;
     3085        }
     3086        auth->auth_ctx = gse_ctx;
     3087
     3088        status = rpc_pipe_bind(result, auth);
     3089        if (!NT_STATUS_IS_OK(status)) {
     3090                DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
     3091                          nt_errstr(status)));
     3092                goto err_out;
     3093        }
     3094
     3095        *presult = result;
     3096        return NT_STATUS_OK;
     3097
     3098err_out:
     3099        TALLOC_FREE(result);
     3100        return status;
     3101}
     3102
     3103NTSTATUS cli_rpc_pipe_open_spnego_krb5(struct cli_state *cli,
     3104                                        const struct ndr_syntax_id *interface,
     3105                                        enum dcerpc_transport_t transport,
     3106                                        enum dcerpc_AuthLevel auth_level,
     3107                                        const char *server,
     3108                                        const char *username,
     3109                                        const char *password,
     3110                                        struct rpc_pipe_client **presult)
     3111{
     3112        struct rpc_pipe_client *result;
     3113        struct pipe_auth_data *auth;
     3114        struct spnego_context *spnego_ctx;
     3115        NTSTATUS status;
     3116
     3117        status = cli_rpc_pipe_open(cli, transport, interface, &result);
     3118        if (!NT_STATUS_IS_OK(status)) {
     3119                return status;
     3120        }
     3121
     3122        auth = talloc(result, struct pipe_auth_data);
     3123        if (auth == NULL) {
     3124                status = NT_STATUS_NO_MEMORY;
     3125                goto err_out;
     3126        }
     3127        auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
     3128        auth->auth_level = auth_level;
     3129
     3130        if (!username) {
     3131                username = "";
     3132        }
     3133        auth->user_name = talloc_strdup(auth, username);
     3134        if (!auth->user_name) {
     3135                status = NT_STATUS_NO_MEMORY;
     3136                goto err_out;
     3137        }
     3138
     3139        /* Fixme, should we fetch/set the Realm ? */
     3140        auth->domain = talloc_strdup(auth, "");
     3141        if (!auth->domain) {
     3142                status = NT_STATUS_NO_MEMORY;
     3143                goto err_out;
     3144        }
     3145
     3146        status = spnego_gssapi_init_client(auth,
     3147                                           (auth->auth_level ==
     3148                                                DCERPC_AUTH_LEVEL_INTEGRITY),
     3149                                           (auth->auth_level ==
     3150                                                DCERPC_AUTH_LEVEL_PRIVACY),
     3151                                           true,
     3152                                           NULL, server, "cifs",
     3153                                           username, password,
     3154                                           &spnego_ctx);
     3155        if (!NT_STATUS_IS_OK(status)) {
     3156                DEBUG(0, ("spnego_init_client returned %s\n",
     3157                          nt_errstr(status)));
     3158                goto err_out;
     3159        }
     3160        auth->auth_ctx = spnego_ctx;
     3161
     3162        status = rpc_pipe_bind(result, auth);
     3163        if (!NT_STATUS_IS_OK(status)) {
     3164                DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
     3165                          nt_errstr(status)));
     3166                goto err_out;
     3167        }
     3168
     3169        *presult = result;
     3170        return NT_STATUS_OK;
     3171
     3172err_out:
     3173        TALLOC_FREE(result);
     3174        return status;
     3175}
    39003176
    39013177NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
     
    39083184                                          struct rpc_pipe_client **presult)
    39093185{
    3910         return cli_rpc_pipe_open_ntlmssp_internal(cli,
    3911                                                 interface,
    3912                                                 transport,
    3913                                                 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
    3914                                                 auth_level,
    3915                                                 domain,
    3916                                                 username,
    3917                                                 password,
    3918                                                 presult);
    3919 }
    3920 
    3921 /****************************************************************************
    3922   Get a the schannel session key out of an already opened netlogon pipe.
    3923  ****************************************************************************/
    3924 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
    3925                                                 struct cli_state *cli,
    3926                                                 const char *domain,
    3927                                                 uint32 *pneg_flags)
    3928 {
    3929         enum netr_SchannelType sec_chan_type = 0;
    3930         unsigned char machine_pwd[16];
    3931         const char *machine_account;
    3932         NTSTATUS status;
    3933 
    3934         /* Get the machine account credentials from secrets.tdb. */
    3935         if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
    3936                                &sec_chan_type))
    3937         {
    3938                 DEBUG(0, ("get_schannel_session_key: could not fetch "
    3939                         "trust account password for domain '%s'\n",
    3940                         domain));
    3941                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
    3942         }
    3943 
    3944         status = rpccli_netlogon_setup_creds(netlogon_pipe,
    3945                                         cli->desthost, /* server name */
    3946                                         domain,        /* domain */
    3947                                         global_myname(), /* client name */
    3948                                         machine_account, /* machine account name */
    3949                                         machine_pwd,
    3950                                         sec_chan_type,
    3951                                         pneg_flags);
    3952 
    3953         if (!NT_STATUS_IS_OK(status)) {
    3954                 DEBUG(3, ("get_schannel_session_key_common: "
    3955                           "rpccli_netlogon_setup_creds failed with result %s "
    3956                           "to server %s, domain %s, machine account %s.\n",
    3957                           nt_errstr(status), cli->desthost, domain,
    3958                           machine_account ));
     3186        struct rpc_pipe_client *result;
     3187        struct pipe_auth_data *auth;
     3188        struct spnego_context *spnego_ctx;
     3189        NTSTATUS status;
     3190
     3191        status = cli_rpc_pipe_open(cli, transport, interface, &result);
     3192        if (!NT_STATUS_IS_OK(status)) {
    39593193                return status;
    39603194        }
    39613195
    3962         if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
    3963                 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
    3964                         cli->desthost));
    3965                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
    3966         }
    3967 
    3968         return NT_STATUS_OK;;
    3969 }
    3970 
    3971 /****************************************************************************
    3972  Open a netlogon pipe and get the schannel session key.
    3973  Now exposed to external callers.
    3974  ****************************************************************************/
    3975 
    3976 
    3977 NTSTATUS get_schannel_session_key(struct cli_state *cli,
    3978                                   const char *domain,
    3979                                   uint32 *pneg_flags,
    3980                                   struct rpc_pipe_client **presult)
    3981 {
    3982         struct rpc_pipe_client *netlogon_pipe = NULL;
    3983         NTSTATUS status;
    3984 
    3985         status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
    3986                                           &netlogon_pipe);
    3987         if (!NT_STATUS_IS_OK(status)) {
    3988                 return status;
    3989         }
    3990 
    3991         status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
    3992                                                  pneg_flags);
    3993         if (!NT_STATUS_IS_OK(status)) {
    3994                 TALLOC_FREE(netlogon_pipe);
    3995                 return status;
    3996         }
    3997 
    3998         *presult = netlogon_pipe;
    3999         return NT_STATUS_OK;
    4000 }
    4001 
    4002 /****************************************************************************
    4003  External interface.
    4004  Open a named pipe to an SMB server and bind using schannel (bind type 68)
    4005  using session_key. sign and seal.
    4006 
    4007  The *pdc will be stolen onto this new pipe
    4008  ****************************************************************************/
    4009 
    4010 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
    4011                                              const struct ndr_syntax_id *interface,
    4012                                              enum dcerpc_transport_t transport,
    4013                                              enum dcerpc_AuthLevel auth_level,
    4014                                              const char *domain,
    4015                                              struct netlogon_creds_CredentialState **pdc,
    4016                                              struct rpc_pipe_client **presult)
    4017 {
    4018         struct rpc_pipe_client *result;
    4019         struct cli_pipe_auth_data *auth;
    4020         NTSTATUS status;
    4021 
    4022         status = cli_rpc_pipe_open(cli, transport, interface, &result);
    4023         if (!NT_STATUS_IS_OK(status)) {
    4024                 return status;
    4025         }
    4026 
    4027         status = rpccli_schannel_bind_data(result, domain, auth_level,
    4028                                            *pdc, &auth);
    4029         if (!NT_STATUS_IS_OK(status)) {
    4030                 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
     3196        auth = talloc(result, struct pipe_auth_data);
     3197        if (auth == NULL) {
     3198                status = NT_STATUS_NO_MEMORY;
     3199                goto err_out;
     3200        }
     3201        auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
     3202        auth->auth_level = auth_level;
     3203
     3204        if (!username) {
     3205                username = "";
     3206        }
     3207        auth->user_name = talloc_strdup(auth, username);
     3208        if (!auth->user_name) {
     3209                status = NT_STATUS_NO_MEMORY;
     3210                goto err_out;
     3211        }
     3212
     3213        if (!domain) {
     3214                domain = "";
     3215        }
     3216        auth->domain = talloc_strdup(auth, domain);
     3217        if (!auth->domain) {
     3218                status = NT_STATUS_NO_MEMORY;
     3219                goto err_out;
     3220        }
     3221
     3222        status = spnego_ntlmssp_init_client(auth,
     3223                                            (auth->auth_level ==
     3224                                                DCERPC_AUTH_LEVEL_INTEGRITY),
     3225                                            (auth->auth_level ==
     3226                                                DCERPC_AUTH_LEVEL_PRIVACY),
     3227                                            true,
     3228                                            domain, username, password,
     3229                                            &spnego_ctx);
     3230        if (!NT_STATUS_IS_OK(status)) {
     3231                DEBUG(0, ("spnego_init_client returned %s\n",
    40313232                          nt_errstr(status)));
    4032                 TALLOC_FREE(result);
    4033                 return status;
    4034         }
     3233                goto err_out;
     3234        }
     3235        auth->auth_ctx = spnego_ctx;
    40353236
    40363237        status = rpc_pipe_bind(result, auth);
    40373238        if (!NT_STATUS_IS_OK(status)) {
    4038                 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
    4039                           "cli_rpc_pipe_bind failed with error %s\n",
    4040                           nt_errstr(status) ));
    4041                 TALLOC_FREE(result);
    4042                 return status;
    4043         }
    4044 
    4045         /*
    4046          * The credentials on a new netlogon pipe are the ones we are passed
    4047          * in - copy them over
    4048          */
    4049         result->dc = netlogon_creds_copy(result, *pdc);
    4050         if (result->dc == NULL) {
    4051                 TALLOC_FREE(result);
    4052                 return NT_STATUS_NO_MEMORY;
    4053         }
    4054 
    4055         DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
    4056                   "for domain %s and bound using schannel.\n",
    4057                   get_pipe_name_from_syntax(talloc_tos(), interface),
    4058                   cli->desthost, domain ));
     3239                DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
     3240                          nt_errstr(status)));
     3241                goto err_out;
     3242        }
    40593243
    40603244        *presult = result;
    40613245        return NT_STATUS_OK;
    4062 }
    4063 
    4064 /****************************************************************************
    4065  Open a named pipe to an SMB server and bind using schannel (bind type 68).
    4066  Fetch the session key ourselves using a temporary netlogon pipe. This
    4067  version uses an ntlmssp auth bound netlogon pipe to get the key.
    4068  ****************************************************************************/
    4069 
    4070 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
    4071                                                       const char *domain,
    4072                                                       const char *username,
    4073                                                       const char *password,
    4074                                                       uint32 *pneg_flags,
    4075                                                       struct rpc_pipe_client **presult)
    4076 {
    4077         struct rpc_pipe_client *netlogon_pipe = NULL;
    4078         NTSTATUS status;
    4079 
    4080         status = cli_rpc_pipe_open_spnego_ntlmssp(
    4081                 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
    4082                 DCERPC_AUTH_LEVEL_PRIVACY,
    4083                 domain, username, password, &netlogon_pipe);
    4084         if (!NT_STATUS_IS_OK(status)) {
    4085                 return status;
    4086         }
    4087 
    4088         status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
    4089                                                  pneg_flags);
    4090         if (!NT_STATUS_IS_OK(status)) {
    4091                 TALLOC_FREE(netlogon_pipe);
    4092                 return status;
    4093         }
    4094 
    4095         *presult = netlogon_pipe;
    4096         return NT_STATUS_OK;
    4097 }
    4098 
    4099 /****************************************************************************
    4100  Open a named pipe to an SMB server and bind using schannel (bind type 68).
    4101  Fetch the session key ourselves using a temporary netlogon pipe. This version
    4102  uses an ntlmssp bind to get the session key.
    4103  ****************************************************************************/
    4104 
    4105 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
    4106                                                  const struct ndr_syntax_id *interface,
    4107                                                  enum dcerpc_transport_t transport,
    4108                                                  enum dcerpc_AuthLevel auth_level,
    4109                                                  const char *domain,
    4110                                                  const char *username,
    4111                                                  const char *password,
    4112                                                  struct rpc_pipe_client **presult)
    4113 {
    4114         uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
    4115         struct rpc_pipe_client *netlogon_pipe = NULL;
    4116         struct rpc_pipe_client *result = NULL;
    4117         NTSTATUS status;
    4118 
    4119         status = get_schannel_session_key_auth_ntlmssp(
    4120                 cli, domain, username, password, &neg_flags, &netlogon_pipe);
    4121         if (!NT_STATUS_IS_OK(status)) {
    4122                 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
    4123                         "key from server %s for domain %s.\n",
    4124                         cli->desthost, domain ));
    4125                 return status;
    4126         }
    4127 
    4128         status = cli_rpc_pipe_open_schannel_with_key(
    4129                 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
    4130                 &result);
    4131 
    4132         /* Now we've bound using the session key we can close the netlog pipe. */
    4133         TALLOC_FREE(netlogon_pipe);
    4134 
    4135         if (NT_STATUS_IS_OK(status)) {
    4136                 *presult = result;
    4137         }
     3246
     3247err_out:
     3248        TALLOC_FREE(result);
    41383249        return status;
    4139 }
    4140 
    4141 /****************************************************************************
    4142  Open a named pipe to an SMB server and bind using schannel (bind type 68).
    4143  Fetch the session key ourselves using a temporary netlogon pipe.
    4144  ****************************************************************************/
    4145 
    4146 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
    4147                                     const struct ndr_syntax_id *interface,
    4148                                     enum dcerpc_transport_t transport,
    4149                                     enum dcerpc_AuthLevel auth_level,
    4150                                     const char *domain,
    4151                                     struct rpc_pipe_client **presult)
    4152 {
    4153         uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
    4154         struct rpc_pipe_client *netlogon_pipe = NULL;
    4155         struct rpc_pipe_client *result = NULL;
    4156         NTSTATUS status;
    4157 
    4158         status = get_schannel_session_key(cli, domain, &neg_flags,
    4159                                           &netlogon_pipe);
    4160         if (!NT_STATUS_IS_OK(status)) {
    4161                 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
    4162                         "key from server %s for domain %s.\n",
    4163                         cli->desthost, domain ));
    4164                 return status;
    4165         }
    4166 
    4167         status = cli_rpc_pipe_open_schannel_with_key(
    4168                 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
    4169                 &result);
    4170 
    4171         /* Now we've bound using the session key we can close the netlog pipe. */
    4172         TALLOC_FREE(netlogon_pipe);
    4173 
    4174         if (NT_STATUS_IS_OK(status)) {
    4175                 *presult = result;
    4176         }
    4177 
    4178         return status;
    4179 }
    4180 
    4181 /****************************************************************************
    4182  Open a named pipe to an SMB server and bind using krb5 (bind type 16).
    4183  The idea is this can be called with service_princ, username and password all
    4184  NULL so long as the caller has a TGT.
    4185  ****************************************************************************/
    4186 
    4187 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
    4188                                 const struct ndr_syntax_id *interface,
    4189                                 enum dcerpc_AuthLevel auth_level,
    4190                                 const char *service_princ,
    4191                                 const char *username,
    4192                                 const char *password,
    4193                                 struct rpc_pipe_client **presult)
    4194 {
    4195 #ifdef HAVE_KRB5
    4196         struct rpc_pipe_client *result;
    4197         struct cli_pipe_auth_data *auth;
    4198         NTSTATUS status;
    4199 
    4200         status = cli_rpc_pipe_open(cli, NCACN_NP, interface, &result);
    4201         if (!NT_STATUS_IS_OK(status)) {
    4202                 return status;
    4203         }
    4204 
    4205         status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
    4206                                            username, password, &auth);
    4207         if (!NT_STATUS_IS_OK(status)) {
    4208                 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
    4209                           nt_errstr(status)));
    4210                 TALLOC_FREE(result);
    4211                 return status;
    4212         }
    4213 
    4214         status = rpc_pipe_bind(result, auth);
    4215         if (!NT_STATUS_IS_OK(status)) {
    4216                 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
    4217                           "with error %s\n", nt_errstr(status)));
    4218                 TALLOC_FREE(result);
    4219                 return status;
    4220         }
    4221 
    4222         *presult = result;
    4223         return NT_STATUS_OK;
    4224 #else
    4225         DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
    4226         return NT_STATUS_NOT_IMPLEMENTED;
    4227 #endif
    42283250}
    42293251
     
    42323254                             DATA_BLOB *session_key)
    42333255{
     3256        struct pipe_auth_data *a = cli->auth;
     3257        struct schannel_state *schannel_auth;
     3258        struct auth_ntlmssp_state *ntlmssp_ctx;
     3259        struct spnego_context *spnego_ctx;
     3260        struct gse_context *gse_ctx;
     3261        DATA_BLOB sk = data_blob_null;
     3262        bool make_dup = false;
     3263
    42343264        if (!session_key || !cli) {
    42353265                return NT_STATUS_INVALID_PARAMETER;
     
    42413271
    42423272        switch (cli->auth->auth_type) {
    4243                 case PIPE_AUTH_TYPE_SCHANNEL:
    4244                         *session_key = data_blob_talloc(mem_ctx,
    4245                                 cli->auth->a_u.schannel_auth->creds->session_key, 16);
    4246                         break;
    4247                 case PIPE_AUTH_TYPE_NTLMSSP:
    4248                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
    4249                         *session_key = data_blob_talloc(mem_ctx,
    4250                                 cli->auth->a_u.ntlmssp_state->session_key.data,
    4251                                 cli->auth->a_u.ntlmssp_state->session_key.length);
    4252                         break;
    4253                 case PIPE_AUTH_TYPE_KRB5:
    4254                 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
    4255                         *session_key = data_blob_talloc(mem_ctx,
    4256                                 cli->auth->a_u.kerberos_auth->session_key.data,
    4257                                 cli->auth->a_u.kerberos_auth->session_key.length);
    4258                         break;
    4259                 case PIPE_AUTH_TYPE_NONE:
    4260                         *session_key = data_blob_talloc(mem_ctx,
    4261                                 cli->auth->user_session_key.data,
    4262                                 cli->auth->user_session_key.length);
    4263                         break;
    4264                 default:
    4265                         return NT_STATUS_NO_USER_SESSION_KEY;
     3273        case DCERPC_AUTH_TYPE_SCHANNEL:
     3274                schannel_auth = talloc_get_type_abort(a->auth_ctx,
     3275                                                      struct schannel_state);
     3276                sk = data_blob_const(schannel_auth->creds->session_key, 16);
     3277                make_dup = true;
     3278                break;
     3279        case DCERPC_AUTH_TYPE_SPNEGO:
     3280                spnego_ctx = talloc_get_type_abort(a->auth_ctx,
     3281                                                   struct spnego_context);
     3282                sk = spnego_get_session_key(mem_ctx, spnego_ctx);
     3283                make_dup = false;
     3284                break;
     3285        case DCERPC_AUTH_TYPE_NTLMSSP:
     3286                ntlmssp_ctx = talloc_get_type_abort(a->auth_ctx,
     3287                                                    struct auth_ntlmssp_state);
     3288                sk = auth_ntlmssp_get_session_key(ntlmssp_ctx);
     3289                make_dup = true;
     3290                break;
     3291        case DCERPC_AUTH_TYPE_KRB5:
     3292                gse_ctx = talloc_get_type_abort(a->auth_ctx,
     3293                                                struct gse_context);
     3294                sk = gse_get_session_key(mem_ctx, gse_ctx);
     3295                make_dup = false;
     3296                break;
     3297        case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
     3298        case DCERPC_AUTH_TYPE_NONE:
     3299                sk = data_blob_const(a->user_session_key.data,
     3300                                     a->user_session_key.length);
     3301                make_dup = true;
     3302                break;
     3303        default:
     3304                break;
     3305        }
     3306
     3307        if (!sk.data) {
     3308                return NT_STATUS_NO_USER_SESSION_KEY;
     3309        }
     3310
     3311        if (make_dup) {
     3312                *session_key = data_blob_dup_talloc(mem_ctx, &sk);
     3313        } else {
     3314                *session_key = sk;
    42663315        }
    42673316
  • vendor/current/source3/rpc_client/cli_samr.c

    r597 r740  
    2323
    2424#include "includes.h"
     25#include "rpc_client/rpc_client.h"
    2526#include "../libcli/auth/libcli_auth.h"
    26 #include "../librpc/gen_ndr/cli_samr.h"
     27#include "../librpc/gen_ndr/ndr_samr_c.h"
     28#include "rpc_client/cli_samr.h"
     29#include "../lib/crypto/arcfour.h"
     30#include "rpc_client/init_lsa.h"
    2731
    2832/* User change password */
    2933
    30 NTSTATUS rpccli_samr_chgpasswd_user(struct rpc_pipe_client *cli,
     34NTSTATUS dcerpc_samr_chgpasswd_user(struct dcerpc_binding_handle *h,
    3135                                    TALLOC_CTX *mem_ctx,
    3236                                    struct policy_handle *user_handle,
    3337                                    const char *newpassword,
    34                                     const char *oldpassword)
    35 {
    36         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
     38                                    const char *oldpassword,
     39                                    NTSTATUS *presult)
     40{
     41        NTSTATUS status;
    3742        struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
    3843
     
    6267        E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
    6368
    64         result = rpccli_samr_ChangePasswordUser(cli, mem_ctx,
     69        status = dcerpc_samr_ChangePasswordUser(h,
     70                                                mem_ctx,
    6571                                                user_handle,
    6672                                                true,
     
    7379                                                &hash5,
    7480                                                true,
    75                                                 &hash6);
     81                                                &hash6,
     82                                                presult);
     83
     84        return status;
     85}
     86
     87NTSTATUS rpccli_samr_chgpasswd_user(struct rpc_pipe_client *cli,
     88                                    TALLOC_CTX *mem_ctx,
     89                                    struct policy_handle *user_handle,
     90                                    const char *newpassword,
     91                                    const char *oldpassword)
     92{
     93        NTSTATUS status;
     94        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
     95
     96        status = dcerpc_samr_chgpasswd_user(cli->binding_handle,
     97                                            mem_ctx,
     98                                            user_handle,
     99                                            newpassword,
     100                                            oldpassword,
     101                                            &result);
     102        if (!NT_STATUS_IS_OK(status)) {
     103                return status;
     104        }
    76105
    77106        return result;
    78107}
    79108
    80 
    81109/* User change password */
    82110
    83 NTSTATUS rpccli_samr_chgpasswd_user2(struct rpc_pipe_client *cli,
     111NTSTATUS dcerpc_samr_chgpasswd_user2(struct dcerpc_binding_handle *h,
    84112                                     TALLOC_CTX *mem_ctx,
     113                                     const char *srv_name_slash,
    85114                                     const char *username,
    86115                                     const char *newpassword,
    87                                      const char *oldpassword)
    88 {
    89         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
     116                                     const char *oldpassword,
     117                                     NTSTATUS *presult)
     118{
     119        NTSTATUS status;
    90120        struct samr_CryptPassword new_nt_password;
    91121        struct samr_CryptPassword new_lm_password;
     
    93123        struct samr_Password old_lanman_hash_enc;
    94124
    95         uchar old_nt_hash[16];
    96         uchar old_lanman_hash[16];
    97         uchar new_nt_hash[16];
    98         uchar new_lanman_hash[16];
     125        uint8_t old_nt_hash[16];
     126        uint8_t old_lanman_hash[16];
     127        uint8_t new_nt_hash[16];
     128        uint8_t new_lanman_hash[16];
    99129        struct lsa_String server, account;
    100130
    101131        DEBUG(10,("rpccli_samr_chgpasswd_user2\n"));
    102132
    103         init_lsa_String(&server, cli->srv_name_slash);
     133        init_lsa_String(&server, srv_name_slash);
    104134        init_lsa_String(&account, username);
    105135
     
    130160        E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.hash);
    131161
    132         result = rpccli_samr_ChangePasswordUser2(cli, mem_ctx,
     162        status = dcerpc_samr_ChangePasswordUser2(h,
     163                                                 mem_ctx,
    133164                                                 &server,
    134165                                                 &account,
     
    137168                                                 true,
    138169                                                 &new_lm_password,
    139                                                  &old_lanman_hash_enc);
     170                                                 &old_lanman_hash_enc,
     171                                                 presult);
     172
     173        return status;
     174}
     175
     176NTSTATUS rpccli_samr_chgpasswd_user2(struct rpc_pipe_client *cli,
     177                                     TALLOC_CTX *mem_ctx,
     178                                     const char *username,
     179                                     const char *newpassword,
     180                                     const char *oldpassword)
     181{
     182        NTSTATUS status;
     183        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
     184
     185        status = dcerpc_samr_chgpasswd_user2(cli->binding_handle,
     186                                             mem_ctx,
     187                                             cli->srv_name_slash,
     188                                             username,
     189                                             newpassword,
     190                                             oldpassword,
     191                                             &result);
     192        if (!NT_STATUS_IS_OK(status)) {
     193                return status;
     194        }
    140195
    141196        return result;
     
    143198
    144199/* User change password given blobs */
     200
     201NTSTATUS dcerpc_samr_chng_pswd_auth_crap(struct dcerpc_binding_handle *h,
     202                                         TALLOC_CTX *mem_ctx,
     203                                         const char *srv_name_slash,
     204                                         const char *username,
     205                                         DATA_BLOB new_nt_password_blob,
     206                                         DATA_BLOB old_nt_hash_enc_blob,
     207                                         DATA_BLOB new_lm_password_blob,
     208                                         DATA_BLOB old_lm_hash_enc_blob,
     209                                         NTSTATUS *presult)
     210{
     211        NTSTATUS status;
     212        struct samr_CryptPassword new_nt_password;
     213        struct samr_CryptPassword new_lm_password;
     214        struct samr_Password old_nt_hash_enc;
     215        struct samr_Password old_lm_hash_enc;
     216        struct lsa_String server, account;
     217
     218        DEBUG(10,("rpccli_samr_chng_pswd_auth_crap\n"));
     219
     220        ZERO_STRUCT(new_nt_password);
     221        ZERO_STRUCT(new_lm_password);
     222        ZERO_STRUCT(old_nt_hash_enc);
     223        ZERO_STRUCT(old_lm_hash_enc);
     224
     225        init_lsa_String(&server, srv_name_slash);
     226        init_lsa_String(&account, username);
     227
     228        if (new_nt_password_blob.data && new_nt_password_blob.length >= 516) {
     229                memcpy(&new_nt_password.data, new_nt_password_blob.data, 516);
     230        }
     231
     232        if (new_lm_password_blob.data && new_lm_password_blob.length >= 516) {
     233                memcpy(&new_lm_password.data, new_lm_password_blob.data, 516);
     234        }
     235
     236        if (old_nt_hash_enc_blob.data && old_nt_hash_enc_blob.length >= 16) {
     237                memcpy(&old_nt_hash_enc.hash, old_nt_hash_enc_blob.data, 16);
     238        }
     239
     240        if (old_lm_hash_enc_blob.data && old_lm_hash_enc_blob.length >= 16) {
     241                memcpy(&old_lm_hash_enc.hash, old_lm_hash_enc_blob.data, 16);
     242        }
     243
     244        status = dcerpc_samr_ChangePasswordUser2(h,
     245                                                 mem_ctx,
     246                                                 &server,
     247                                                 &account,
     248                                                 &new_nt_password,
     249                                                 &old_nt_hash_enc,
     250                                                 true,
     251                                                 &new_lm_password,
     252                                                 &old_lm_hash_enc,
     253                                                 presult);
     254
     255        return status;
     256}
    145257
    146258NTSTATUS rpccli_samr_chng_pswd_auth_crap(struct rpc_pipe_client *cli,
     
    152264                                         DATA_BLOB old_lm_hash_enc_blob)
    153265{
     266        NTSTATUS status;
    154267        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
    155         struct samr_CryptPassword new_nt_password;
    156         struct samr_CryptPassword new_lm_password;
    157         struct samr_Password old_nt_hash_enc;
    158         struct samr_Password old_lm_hash_enc;
    159         struct lsa_String server, account;
    160 
    161         ZERO_STRUCT(new_nt_password);
    162         ZERO_STRUCT(new_lm_password);
    163         ZERO_STRUCT(old_nt_hash_enc);
    164         ZERO_STRUCT(old_lm_hash_enc);
    165 
    166         DEBUG(10,("rpccli_samr_chng_pswd_auth_crap\n"));
    167 
    168         init_lsa_String(&server, cli->srv_name_slash);
    169         init_lsa_String(&account, username);
    170 
    171         if (new_nt_password_blob.data && new_nt_password_blob.length >= 516) {
    172                 memcpy(&new_nt_password.data, new_nt_password_blob.data, 516);
    173         }
    174         if (new_lm_password_blob.data && new_lm_password_blob.length >= 516) {
    175                 memcpy(&new_lm_password.data, new_lm_password_blob.data, 516);
    176         }
    177         if (old_nt_hash_enc_blob.data && old_nt_hash_enc_blob.length >= 16) {
    178                 memcpy(&old_nt_hash_enc.hash, old_nt_hash_enc_blob.data, 16);
    179         }
    180         if (old_lm_hash_enc_blob.data && old_lm_hash_enc_blob.length >= 16) {
    181                 memcpy(&old_lm_hash_enc.hash, old_lm_hash_enc_blob.data, 16);
    182         }
    183 
    184         result = rpccli_samr_ChangePasswordUser2(cli, mem_ctx,
    185                                                  &server,
    186                                                  &account,
    187                                                  &new_nt_password,
    188                                                  &old_nt_hash_enc,
    189                                                  true,
    190                                                  &new_lm_password,
    191                                                  &old_lm_hash_enc);
     268
     269        status = dcerpc_samr_chng_pswd_auth_crap(cli->binding_handle,
     270                                                 mem_ctx,
     271                                                 cli->srv_name_slash,
     272                                                 username,
     273                                                 new_nt_password_blob,
     274                                                 old_nt_hash_enc_blob,
     275                                                 new_lm_password_blob,
     276                                                 old_lm_hash_enc_blob,
     277                                                 &result);
     278        if (!NT_STATUS_IS_OK(status)) {
     279                return status;
     280        }
     281
    192282        return result;
    193283}
    194284
    195 
    196285/* change password 3 */
    197286
    198 NTSTATUS rpccli_samr_chgpasswd_user3(struct rpc_pipe_client *cli,
     287NTSTATUS dcerpc_samr_chgpasswd_user3(struct dcerpc_binding_handle *h,
    199288                                     TALLOC_CTX *mem_ctx,
     289                                     const char *srv_name_slash,
    200290                                     const char *username,
    201291                                     const char *newpassword,
    202292                                     const char *oldpassword,
    203293                                     struct samr_DomInfo1 **dominfo1,
    204                                      struct samr_ChangeReject **reject)
     294                                     struct userPwdChangeFailureInformation **reject,
     295                                     NTSTATUS *presult)
    205296{
    206297        NTSTATUS status;
     
    211302        struct samr_Password old_lanman_hash_enc;
    212303
    213         uchar old_nt_hash[16];
    214         uchar old_lanman_hash[16];
    215         uchar new_nt_hash[16];
    216         uchar new_lanman_hash[16];
     304        uint8_t old_nt_hash[16];
     305        uint8_t old_lanman_hash[16];
     306        uint8_t new_nt_hash[16];
     307        uint8_t new_lanman_hash[16];
    217308
    218309        struct lsa_String server, account;
     
    220311        DEBUG(10,("rpccli_samr_chgpasswd_user3\n"));
    221312
    222         init_lsa_String(&server, cli->srv_name_slash);
     313        init_lsa_String(&server, srv_name_slash);
    223314        init_lsa_String(&account, username);
    224315
     
    249340        E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.hash);
    250341
    251         status = rpccli_samr_ChangePasswordUser3(cli, mem_ctx,
     342        status = dcerpc_samr_ChangePasswordUser3(h,
     343                                                 mem_ctx,
    252344                                                 &server,
    253345                                                 &account,
     
    259351                                                 NULL,
    260352                                                 dominfo1,
    261                                                  reject);
     353                                                 reject,
     354                                                 presult);
     355
    262356        return status;
     357}
     358
     359NTSTATUS rpccli_samr_chgpasswd_user3(struct rpc_pipe_client *cli,
     360                                     TALLOC_CTX *mem_ctx,
     361                                     const char *username,
     362                                     const char *newpassword,
     363                                     const char *oldpassword,
     364                                     struct samr_DomInfo1 **dominfo1,
     365                                     struct userPwdChangeFailureInformation **reject)
     366{
     367        NTSTATUS status;
     368        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
     369
     370        status = dcerpc_samr_chgpasswd_user3(cli->binding_handle,
     371                                             mem_ctx,
     372                                             cli->srv_name_slash,
     373                                             username,
     374                                             newpassword,
     375                                             oldpassword,
     376                                             dominfo1,
     377                                             reject,
     378                                             &result);
     379        if (!NT_STATUS_IS_OK(status)) {
     380                return status;
     381        }
     382
     383        return result;
    263384}
    264385
     
    268389   obtained by inspection using ethereal and NT4 running User Manager. */
    269390
    270 void get_query_dispinfo_params(int loop_count, uint32 *max_entries,
    271                                uint32 *max_size)
     391void dcerpc_get_query_dispinfo_params(int loop_count,
     392                                      uint32_t *max_entries,
     393                                      uint32_t *max_size)
    272394{
    273395        switch(loop_count) {
     
    295417}
    296418
    297 NTSTATUS rpccli_try_samr_connects(struct rpc_pipe_client *cli,
     419NTSTATUS dcerpc_try_samr_connects(struct dcerpc_binding_handle *h,
    298420                                  TALLOC_CTX *mem_ctx,
     421                                  const char *srv_name_slash,
    299422                                  uint32_t access_mask,
    300                                   struct policy_handle *connect_pol)
     423                                  struct policy_handle *connect_pol,
     424                                  NTSTATUS *presult)
    301425{
    302426        NTSTATUS status;
     
    310434        info_in.info1 = info1;
    311435
    312         status = rpccli_samr_Connect5(cli, mem_ctx,
    313                                       cli->srv_name_slash,
     436        status = dcerpc_samr_Connect5(h,
     437                                      mem_ctx,
     438                                      srv_name_slash,
    314439                                      access_mask,
    315440                                      1,
     
    317442                                      &lvl_out,
    318443                                      &info_out,
    319                                       connect_pol);
    320         if (NT_STATUS_IS_OK(status)) {
    321                 return status;
    322         }
    323 
    324         status = rpccli_samr_Connect4(cli, mem_ctx,
    325                                       cli->srv_name_slash,
     444                                      connect_pol,
     445                                      presult);
     446        if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(*presult)) {
     447                return status;
     448        }
     449
     450        status = dcerpc_samr_Connect4(h,
     451                                      mem_ctx,
     452                                      srv_name_slash,
    326453                                      SAMR_CONNECT_W2K,
    327454                                      access_mask,
    328                                       connect_pol);
    329         if (NT_STATUS_IS_OK(status)) {
    330                 return status;
    331         }
    332 
    333         status = rpccli_samr_Connect2(cli, mem_ctx,
    334                                       cli->srv_name_slash,
     455                                      connect_pol,
     456                                      presult);
     457        if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(*presult)) {
     458                return status;
     459        }
     460
     461        status = dcerpc_samr_Connect2(h,
     462                                      mem_ctx,
     463                                      srv_name_slash,
    335464                                      access_mask,
    336                                       connect_pol);
     465                                      connect_pol,
     466                                      presult);
     467
    337468        return status;
    338469}
    339470
     471NTSTATUS rpccli_try_samr_connects(struct rpc_pipe_client *cli,
     472                                  TALLOC_CTX *mem_ctx,
     473                                  uint32_t access_mask,
     474                                  struct policy_handle *connect_pol)
     475{
     476        NTSTATUS status;
     477        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
     478
     479        status = dcerpc_try_samr_connects(cli->binding_handle,
     480                                          mem_ctx,
     481                                          cli->srv_name_slash,
     482                                          access_mask,
     483                                          connect_pol,
     484                                          &result);
     485        if (!NT_STATUS_IS_OK(status)) {
     486                return status;
     487        }
     488
     489        return result;
     490}
     491
     492/* vim: set ts=8 sw=8 noet cindent: */
  • vendor/current/source3/rpc_client/cli_spoolss.c

    r427 r740  
    2424
    2525#include "includes.h"
    26 #include "../librpc/gen_ndr/cli_spoolss.h"
     26#include "rpc_client/rpc_client.h"
     27#include "../librpc/gen_ndr/ndr_spoolss_c.h"
     28#include "rpc_client/cli_spoolss.h"
    2729
    2830/**********************************************************************
     
    4143        union spoolss_UserLevel userlevel;
    4244        struct spoolss_UserLevel1 level1;
     45        struct dcerpc_binding_handle *b = cli->binding_handle;
    4346
    4447        ZERO_STRUCT(devmode_ctr);
     
    5558        userlevel.level1 = &level1;
    5659
    57         status = rpccli_spoolss_OpenPrinterEx(cli, mem_ctx,
     60        status = dcerpc_spoolss_OpenPrinterEx(b, mem_ctx,
    5861                                              printername,
    5962                                              NULL,
     
    6568                                              &werror);
    6669
     70        if (!NT_STATUS_IS_OK(status)) {
     71                return ntstatus_to_werror(status);
     72        }
     73
    6774        if (!W_ERROR_IS_OK(werror)) {
    6875                return werror;
    69         }
    70 
    71         if (!NT_STATUS_IS_OK(status)) {
    72                 return ntstatus_to_werror(status);
    7376        }
    7477
     
    9295        uint32_t needed;
    9396        DATA_BLOB buffer;
    94 
    95         if (offered > 0) {
    96                 buffer = data_blob_talloc_zero(mem_ctx, offered);
    97                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
    98         }
    99 
    100         status = rpccli_spoolss_GetPrinterDriver(cli, mem_ctx,
     97        struct dcerpc_binding_handle *b = cli->binding_handle;
     98
     99        if (offered > 0) {
     100                buffer = data_blob_talloc_zero(mem_ctx, offered);
     101                W_ERROR_HAVE_NO_MEMORY(buffer.data);
     102        }
     103
     104        status = dcerpc_spoolss_GetPrinterDriver(b, mem_ctx,
    101105                                                 handle,
    102106                                                 architecture,
     
    107111                                                 &needed,
    108112                                                 &werror);
     113        if (!NT_STATUS_IS_OK(status)) {
     114                return ntstatus_to_werror(status);
     115        }
    109116        if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
    110117                offered = needed;
     
    112119                W_ERROR_HAVE_NO_MEMORY(buffer.data);
    113120
    114                 status = rpccli_spoolss_GetPrinterDriver(cli, mem_ctx,
     121                status = dcerpc_spoolss_GetPrinterDriver(b, mem_ctx,
    115122                                                         handle,
    116123                                                         architecture,
     
    121128                                                         &needed,
    122129                                                         &werror);
     130        }
     131        if (!NT_STATUS_IS_OK(status)) {
     132                return ntstatus_to_werror(status);
    123133        }
    124134
     
    146156        uint32_t needed;
    147157        DATA_BLOB buffer;
    148 
    149         if (offered > 0) {
    150                 buffer = data_blob_talloc_zero(mem_ctx, offered);
    151                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
    152         }
    153 
    154         status = rpccli_spoolss_GetPrinterDriver2(cli, mem_ctx,
     158        struct dcerpc_binding_handle *b = cli->binding_handle;
     159
     160        if (offered > 0) {
     161                buffer = data_blob_talloc_zero(mem_ctx, offered);
     162                W_ERROR_HAVE_NO_MEMORY(buffer.data);
     163        }
     164
     165        status = dcerpc_spoolss_GetPrinterDriver2(b, mem_ctx,
    155166                                                  handle,
    156167                                                  architecture,
     
    165176                                                  server_minor_version,
    166177                                                  &werror);
     178        if (!NT_STATUS_IS_OK(status)) {
     179                return ntstatus_to_werror(status);
     180        }
     181
    167182        if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
    168183                offered = needed;
     
    170185                W_ERROR_HAVE_NO_MEMORY(buffer.data);
    171186
    172                 status = rpccli_spoolss_GetPrinterDriver2(cli, mem_ctx,
     187                status = dcerpc_spoolss_GetPrinterDriver2(b, mem_ctx,
    173188                                                          handle,
    174189                                                          architecture,
     
    184199                                                          &werror);
    185200        }
     201        if (!NT_STATUS_IS_OK(status)) {
     202                return ntstatus_to_werror(status);
     203        }
    186204
    187205        return werror;
     
    203221        struct spoolss_UserLevel1 level1;
    204222        struct policy_handle handle;
     223        struct dcerpc_binding_handle *b = cli->binding_handle;
    205224
    206225        ZERO_STRUCT(devmode_ctr);
     
    219238        userlevel_ctr.user_info.level1 = &level1;
    220239
    221         status = rpccli_spoolss_AddPrinterEx(cli, mem_ctx,
     240        status = dcerpc_spoolss_AddPrinterEx(b, mem_ctx,
    222241                                             cli->srv_name_slash,
    223242                                             info_ctr,
     
    227246                                             &handle,
    228247                                             &result);
     248        if (!NT_STATUS_IS_OK(status)) {
     249                return ntstatus_to_werror(status);
     250        }
     251
    229252        return result;
    230253}
     
    245268        DATA_BLOB buffer;
    246269        uint32_t needed;
    247 
    248         if (offered > 0) {
    249                 buffer = data_blob_talloc_zero(mem_ctx, offered);
    250                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
    251         }
    252 
    253         status = rpccli_spoolss_GetPrinter(cli, mem_ctx,
     270        struct dcerpc_binding_handle *b = cli->binding_handle;
     271
     272        if (offered > 0) {
     273                buffer = data_blob_talloc_zero(mem_ctx, offered);
     274                W_ERROR_HAVE_NO_MEMORY(buffer.data);
     275        }
     276
     277        status = dcerpc_spoolss_GetPrinter(b, mem_ctx,
    254278                                           handle,
    255279                                           level,
     
    259283                                           &needed,
    260284                                           &werror);
    261 
    262         if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
    263 
    264                 offered = needed;
    265                 buffer = data_blob_talloc_zero(mem_ctx, offered);
    266                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
    267 
    268                 status = rpccli_spoolss_GetPrinter(cli, mem_ctx,
     285        if (!NT_STATUS_IS_OK(status)) {
     286                return ntstatus_to_werror(status);
     287        }
     288
     289        if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
     290
     291                offered = needed;
     292                buffer = data_blob_talloc_zero(mem_ctx, offered);
     293                W_ERROR_HAVE_NO_MEMORY(buffer.data);
     294
     295                status = dcerpc_spoolss_GetPrinter(b, mem_ctx,
    269296                                                   handle,
    270297                                                   level,
     
    275302                                                   &werror);
    276303        }
     304        if (!NT_STATUS_IS_OK(status)) {
     305                return ntstatus_to_werror(status);
     306        }
    277307
    278308        return werror;
     
    295325        uint32_t needed;
    296326        DATA_BLOB buffer;
    297 
    298         if (offered > 0) {
    299                 buffer = data_blob_talloc_zero(mem_ctx, offered);
    300                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
    301         }
    302 
    303         status = rpccli_spoolss_GetJob(cli, mem_ctx,
     327        struct dcerpc_binding_handle *b = cli->binding_handle;
     328
     329        if (offered > 0) {
     330                buffer = data_blob_talloc_zero(mem_ctx, offered);
     331                W_ERROR_HAVE_NO_MEMORY(buffer.data);
     332        }
     333
     334        status = dcerpc_spoolss_GetJob(b, mem_ctx,
    304335                                       handle,
    305336                                       job_id,
     
    310341                                       &needed,
    311342                                       &werror);
     343        if (!NT_STATUS_IS_OK(status)) {
     344                return ntstatus_to_werror(status);
     345        }
    312346
    313347        if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
     
    316350                W_ERROR_HAVE_NO_MEMORY(buffer.data);
    317351
    318                 status = rpccli_spoolss_GetJob(cli, mem_ctx,
     352                status = dcerpc_spoolss_GetJob(b, mem_ctx,
    319353                                               handle,
    320354                                               job_id,
     
    326360                                               &werror);
    327361        }
     362        if (!NT_STATUS_IS_OK(status)) {
     363                return ntstatus_to_werror(status);
     364        }
    328365
    329366        return werror;
     
    346383        uint32_t needed;
    347384        DATA_BLOB buffer;
    348 
    349         if (offered > 0) {
    350                 buffer = data_blob_talloc_zero(mem_ctx, offered);
    351                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
    352         }
    353 
    354         status = rpccli_spoolss_EnumForms(cli, mem_ctx,
     385        struct dcerpc_binding_handle *b = cli->binding_handle;
     386
     387        if (offered > 0) {
     388                buffer = data_blob_talloc_zero(mem_ctx, offered);
     389                W_ERROR_HAVE_NO_MEMORY(buffer.data);
     390        }
     391
     392        status = dcerpc_spoolss_EnumForms(b, mem_ctx,
    355393                                          handle,
    356394                                          level,
     
    361399                                          &needed,
    362400                                          &werror);
     401        if (!NT_STATUS_IS_OK(status)) {
     402                return ntstatus_to_werror(status);
     403        }
    363404
    364405        if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
     
    367408                W_ERROR_HAVE_NO_MEMORY(buffer.data);
    368409
    369                 status = rpccli_spoolss_EnumForms(cli, mem_ctx,
     410                status = dcerpc_spoolss_EnumForms(b, mem_ctx,
    370411                                                  handle,
    371412                                                  level,
     
    377418                                                  &werror);
    378419        }
     420        if (!NT_STATUS_IS_OK(status)) {
     421                return ntstatus_to_werror(status);
     422        }
    379423
    380424        return werror;
     
    398442        uint32_t needed;
    399443        DATA_BLOB buffer;
    400 
    401         if (offered > 0) {
    402                 buffer = data_blob_talloc_zero(mem_ctx, offered);
    403                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
    404         }
    405 
    406         status = rpccli_spoolss_EnumPrintProcessors(cli, mem_ctx,
     444        struct dcerpc_binding_handle *b = cli->binding_handle;
     445
     446        if (offered > 0) {
     447                buffer = data_blob_talloc_zero(mem_ctx, offered);
     448                W_ERROR_HAVE_NO_MEMORY(buffer.data);
     449        }
     450
     451        status = dcerpc_spoolss_EnumPrintProcessors(b, mem_ctx,
    407452                                                    servername,
    408453                                                    environment,
     
    414459                                                    &needed,
    415460                                                    &werror);
     461        if (!NT_STATUS_IS_OK(status)) {
     462                return ntstatus_to_werror(status);
     463        }
    416464
    417465        if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
     
    420468                W_ERROR_HAVE_NO_MEMORY(buffer.data);
    421469
    422                 status = rpccli_spoolss_EnumPrintProcessors(cli, mem_ctx,
     470                status = dcerpc_spoolss_EnumPrintProcessors(b, mem_ctx,
    423471                                                            servername,
    424472                                                            environment,
     
    431479                                                            &werror);
    432480        }
     481        if (!NT_STATUS_IS_OK(status)) {
     482                return ntstatus_to_werror(status);
     483        }
    433484
    434485        return werror;
     
    452503        uint32_t needed;
    453504        DATA_BLOB buffer;
    454 
    455         if (offered > 0) {
    456                 buffer = data_blob_talloc_zero(mem_ctx, offered);
    457                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
    458         }
    459 
    460         status = rpccli_spoolss_EnumPrintProcDataTypes(cli, mem_ctx,
     505        struct dcerpc_binding_handle *b = cli->binding_handle;
     506
     507        if (offered > 0) {
     508                buffer = data_blob_talloc_zero(mem_ctx, offered);
     509                W_ERROR_HAVE_NO_MEMORY(buffer.data);
     510        }
     511
     512        status = dcerpc_spoolss_EnumPrintProcDataTypes(b, mem_ctx,
    461513                                                       servername,
    462514                                                       print_processor_name,
     
    468520                                                       &needed,
    469521                                                       &werror);
     522        if (!NT_STATUS_IS_OK(status)) {
     523                return ntstatus_to_werror(status);
     524        }
    470525
    471526        if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
     
    474529                W_ERROR_HAVE_NO_MEMORY(buffer.data);
    475530
    476                 status = rpccli_spoolss_EnumPrintProcDataTypes(cli, mem_ctx,
     531                status = dcerpc_spoolss_EnumPrintProcDataTypes(b, mem_ctx,
    477532                                                               servername,
    478533                                                               print_processor_name,
     
    485540                                                               &werror);
    486541        }
     542        if (!NT_STATUS_IS_OK(status)) {
     543                return ntstatus_to_werror(status);
     544        }
    487545
    488546        return werror;
     
    505563        uint32_t needed;
    506564        DATA_BLOB buffer;
    507 
    508         if (offered > 0) {
    509                 buffer = data_blob_talloc_zero(mem_ctx, offered);
    510                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
    511         }
    512 
    513         status = rpccli_spoolss_EnumPorts(cli, mem_ctx,
     565        struct dcerpc_binding_handle *b = cli->binding_handle;
     566
     567        if (offered > 0) {
     568                buffer = data_blob_talloc_zero(mem_ctx, offered);
     569                W_ERROR_HAVE_NO_MEMORY(buffer.data);
     570        }
     571
     572        status = dcerpc_spoolss_EnumPorts(b, mem_ctx,
    514573                                          servername,
    515574                                          level,
     
    520579                                          &needed,
    521580                                          &werror);
     581        if (!NT_STATUS_IS_OK(status)) {
     582                return ntstatus_to_werror(status);
     583        }
    522584
    523585        if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
     
    526588                W_ERROR_HAVE_NO_MEMORY(buffer.data);
    527589
    528                 status = rpccli_spoolss_EnumPorts(cli, mem_ctx,
     590                status = dcerpc_spoolss_EnumPorts(b, mem_ctx,
    529591                                                  servername,
    530592                                                  level,
     
    536598                                                  &werror);
    537599        }
     600        if (!NT_STATUS_IS_OK(status)) {
     601                return ntstatus_to_werror(status);
     602        }
    538603
    539604        return werror;
     
    556621        uint32_t needed;
    557622        DATA_BLOB buffer;
    558 
    559         if (offered > 0) {
    560                 buffer = data_blob_talloc_zero(mem_ctx, offered);
    561                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
    562         }
    563 
    564         status = rpccli_spoolss_EnumMonitors(cli, mem_ctx,
     623        struct dcerpc_binding_handle *b = cli->binding_handle;
     624
     625        if (offered > 0) {
     626                buffer = data_blob_talloc_zero(mem_ctx, offered);
     627                W_ERROR_HAVE_NO_MEMORY(buffer.data);
     628        }
     629
     630        status = dcerpc_spoolss_EnumMonitors(b, mem_ctx,
    565631                                             servername,
    566632                                             level,
     
    571637                                             &needed,
    572638                                             &werror);
     639        if (!NT_STATUS_IS_OK(status)) {
     640                return ntstatus_to_werror(status);
     641        }
    573642
    574643        if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
     
    577646                W_ERROR_HAVE_NO_MEMORY(buffer.data);
    578647
    579                 status = rpccli_spoolss_EnumMonitors(cli, mem_ctx,
     648                status = dcerpc_spoolss_EnumMonitors(b, mem_ctx,
    580649                                                     servername,
    581650                                                     level,
     
    586655                                                     &needed,
    587656                                                     &werror);
     657        }
     658        if (!NT_STATUS_IS_OK(status)) {
     659                return ntstatus_to_werror(status);
    588660        }
    589661
     
    609681        uint32_t needed;
    610682        DATA_BLOB buffer;
    611 
    612         if (offered > 0) {
    613                 buffer = data_blob_talloc_zero(mem_ctx, offered);
    614                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
    615         }
    616 
    617         status = rpccli_spoolss_EnumJobs(cli, mem_ctx,
     683        struct dcerpc_binding_handle *b = cli->binding_handle;
     684
     685        if (offered > 0) {
     686                buffer = data_blob_talloc_zero(mem_ctx, offered);
     687                W_ERROR_HAVE_NO_MEMORY(buffer.data);
     688        }
     689
     690        status = dcerpc_spoolss_EnumJobs(b, mem_ctx,
    618691                                         handle,
    619692                                         firstjob,
     
    626699                                         &needed,
    627700                                         &werror);
     701        if (!NT_STATUS_IS_OK(status)) {
     702                return ntstatus_to_werror(status);
     703        }
    628704
    629705        if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
     
    632708                W_ERROR_HAVE_NO_MEMORY(buffer.data);
    633709
    634                 status = rpccli_spoolss_EnumJobs(cli, mem_ctx,
     710                status = dcerpc_spoolss_EnumJobs(b, mem_ctx,
    635711                                                 handle,
    636712                                                 firstjob,
     
    644720                                                 &werror);
    645721        }
     722        if (!NT_STATUS_IS_OK(status)) {
     723                return ntstatus_to_werror(status);
     724        }
    646725
    647726        return werror;
     
    665744        uint32_t needed;
    666745        DATA_BLOB buffer;
    667 
    668         if (offered > 0) {
    669                 buffer = data_blob_talloc_zero(mem_ctx, offered);
    670                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
    671         }
    672 
    673         status = rpccli_spoolss_EnumPrinterDrivers(cli, mem_ctx,
     746        struct dcerpc_binding_handle *b = cli->binding_handle;
     747
     748        if (offered > 0) {
     749                buffer = data_blob_talloc_zero(mem_ctx, offered);
     750                W_ERROR_HAVE_NO_MEMORY(buffer.data);
     751        }
     752
     753        status = dcerpc_spoolss_EnumPrinterDrivers(b, mem_ctx,
    674754                                                   server,
    675755                                                   environment,
     
    681761                                                   &needed,
    682762                                                   &werror);
     763        if (!NT_STATUS_IS_OK(status)) {
     764                return ntstatus_to_werror(status);
     765        }
    683766
    684767        if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
     
    687770                W_ERROR_HAVE_NO_MEMORY(buffer.data);
    688771
    689                 status = rpccli_spoolss_EnumPrinterDrivers(cli, mem_ctx,
     772                status = dcerpc_spoolss_EnumPrinterDrivers(b, mem_ctx,
    690773                                                   server,
    691774                                                   environment,
     
    698781                                                   &werror);
    699782        }
     783        if (!NT_STATUS_IS_OK(status)) {
     784                return ntstatus_to_werror(status);
     785        }
    700786
    701787        return werror;
     
    719805        uint32_t needed;
    720806        DATA_BLOB buffer;
    721 
    722         if (offered > 0) {
    723                 buffer = data_blob_talloc_zero(mem_ctx, offered);
    724                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
    725         }
    726 
    727         status = rpccli_spoolss_EnumPrinters(cli, mem_ctx,
     807        struct dcerpc_binding_handle *b = cli->binding_handle;
     808
     809        if (offered > 0) {
     810                buffer = data_blob_talloc_zero(mem_ctx, offered);
     811                W_ERROR_HAVE_NO_MEMORY(buffer.data);
     812        }
     813
     814        status = dcerpc_spoolss_EnumPrinters(b, mem_ctx,
    728815                                             flags,
    729816                                             server,
     
    735822                                             &needed,
    736823                                             &werror);
     824        if (!NT_STATUS_IS_OK(status)) {
     825                return ntstatus_to_werror(status);
     826        }
    737827
    738828        if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
     
    741831                W_ERROR_HAVE_NO_MEMORY(buffer.data);
    742832
    743                 status = rpccli_spoolss_EnumPrinters(cli, mem_ctx,
     833                status = dcerpc_spoolss_EnumPrinters(b, mem_ctx,
    744834                                                     flags,
    745835                                                     server,
     
    752842                                                     &werror);
    753843        }
     844        if (!NT_STATUS_IS_OK(status)) {
     845                return ntstatus_to_werror(status);
     846        }
    754847
    755848        return werror;
     
    773866        uint32_t needed;
    774867        uint8_t *data;
     868        struct dcerpc_binding_handle *b = cli->binding_handle;
    775869
    776870        data = talloc_zero_array(mem_ctx, uint8_t, offered);
    777871        W_ERROR_HAVE_NO_MEMORY(data);
    778872
    779         status = rpccli_spoolss_GetPrinterData(cli, mem_ctx,
     873        status = dcerpc_spoolss_GetPrinterData(b, mem_ctx,
    780874                                               handle,
    781875                                               value_name,
     
    785879                                               &needed,
    786880                                               &werror);
     881        if (!NT_STATUS_IS_OK(status)) {
     882                return ntstatus_to_werror(status);
     883        }
    787884
    788885        if (W_ERROR_EQUAL(werror, WERR_MORE_DATA)) {
     
    791888                W_ERROR_HAVE_NO_MEMORY(data);
    792889
    793                 status = rpccli_spoolss_GetPrinterData(cli, mem_ctx,
     890                status = dcerpc_spoolss_GetPrinterData(b, mem_ctx,
    794891                                                       handle,
    795892                                                       value_name,
     
    800897                                                       &werror);
    801898        }
     899        if (!NT_STATUS_IS_OK(status)) {
     900                return ntstatus_to_werror(status);
     901        }
    802902
    803903        *data_p = data;
     
    823923        union spoolss_KeyNames _key_buffer;
    824924        uint32_t _ndr_size;
    825 
    826         status = rpccli_spoolss_EnumPrinterKey(cli, mem_ctx,
     925        struct dcerpc_binding_handle *b = cli->binding_handle;
     926
     927        status = dcerpc_spoolss_EnumPrinterKey(b, mem_ctx,
    827928                                               handle,
    828929                                               key_name,
     
    832933                                               &needed,
    833934                                               &werror);
     935        if (!NT_STATUS_IS_OK(status)) {
     936                return ntstatus_to_werror(status);
     937        }
    834938
    835939        if (W_ERROR_EQUAL(werror, WERR_MORE_DATA)) {
    836940                offered = needed;
    837                 status = rpccli_spoolss_EnumPrinterKey(cli, mem_ctx,
     941                status = dcerpc_spoolss_EnumPrinterKey(b, mem_ctx,
    838942                                                       handle,
    839943                                                       key_name,
     
    844948                                                       &werror);
    845949        }
     950        if (!NT_STATUS_IS_OK(status)) {
     951                return ntstatus_to_werror(status);
     952        }
    846953
    847954        *key_buffer = _key_buffer.string_array;
     
    865972        WERROR werror;
    866973        uint32_t needed;
    867 
    868         status = rpccli_spoolss_EnumPrinterDataEx(cli, mem_ctx,
     974        struct dcerpc_binding_handle *b = cli->binding_handle;
     975
     976        status = dcerpc_spoolss_EnumPrinterDataEx(b, mem_ctx,
    869977                                                  handle,
    870978                                                  key_name,
     
    874982                                                  &needed,
    875983                                                  &werror);
     984        if (!NT_STATUS_IS_OK(status)) {
     985                return ntstatus_to_werror(status);
     986        }
    876987
    877988        if (W_ERROR_EQUAL(werror, WERR_MORE_DATA)) {
    878989                offered = needed;
    879990
    880                 status = rpccli_spoolss_EnumPrinterDataEx(cli, mem_ctx,
     991                status = dcerpc_spoolss_EnumPrinterDataEx(b, mem_ctx,
    881992                                                          handle,
    882993                                                          key_name,
     
    887998                                                          &werror);
    888999        }
    889 
    890         return werror;
    891 }
     1000        if (!NT_STATUS_IS_OK(status)) {
     1001                return ntstatus_to_werror(status);
     1002        }
     1003
     1004        return werror;
     1005}
  • vendor/current/source3/rpc_client/init_lsa.c

    r414 r740  
    1919
    2020#include "includes.h"
     21#include "rpc_client/init_lsa.h"
     22#include "../librpc/gen_ndr/lsa.h"
    2123
    2224/*******************************************************************
  • vendor/current/source3/rpc_client/init_netlogon.c

    r414 r740  
    2020#include "includes.h"
    2121#include "../libcli/auth/libcli_auth.h"
     22#include "../lib/crypto/arcfour.h"
     23#include "rpc_client/init_netlogon.h"
    2224
    2325/*************************************************************************
  • vendor/current/source3/rpc_client/init_samr.c

    r414 r740  
    2020#include "includes.h"
    2121#include "../libcli/auth/libcli_auth.h"
     22#include "../lib/crypto/md5.h"
     23#include "../lib/crypto/arcfour.h"
     24#include "rpc_client/init_samr.h"
    2225
    2326/*************************************************************************
  • vendor/current/source3/rpc_client/init_spoolss.c

    r587 r740  
    1919
    2020#include "includes.h"
     21#include "../librpc/gen_ndr/ndr_spoolss.h"
     22#include "rpc_client/init_spoolss.h"
     23#include "../libcli/security/security.h"
     24#include "secrets.h"
     25#include "passdb/machine_sid.h"
    2126
    2227/*******************************************************************
     
    4247}
    4348
     49time_t spoolss_Time_to_time_t(const struct spoolss_Time *r)
     50{
     51        struct tm unixtime;
     52
     53        unixtime.tm_year        = r->year - 1900;
     54        unixtime.tm_mon         = r->month - 1;
     55        unixtime.tm_wday        = r->day_of_week;
     56        unixtime.tm_mday        = r->day;
     57        unixtime.tm_hour        = r->hour;
     58        unixtime.tm_min         = r->minute;
     59        unixtime.tm_sec         = r->second;
     60
     61        return mktime(&unixtime);
     62}
     63
    4464/*******************************************************************
    4565 ********************************************************************/
     
    5171{
    5272        enum ndr_err_code ndr_err;
    53         ndr_err = ndr_pull_union_blob(blob, mem_ctx, NULL, data, type,
     73        ndr_err = ndr_pull_union_blob(blob, mem_ctx, data, type,
    5474                        (ndr_pull_flags_fn_t)ndr_pull_spoolss_PrinterData);
    5575        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     
    6787{
    6888        enum ndr_err_code ndr_err;
    69         ndr_err = ndr_push_union_blob(blob, mem_ctx, NULL, data, type,
     89        ndr_err = ndr_push_union_blob(blob, mem_ctx, data, type,
    7090                        (ndr_push_flags_fn_t)ndr_push_spoolss_PrinterData);
    7191        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     
    103123        s->averageppm           = i->averageppm;
    104124}
     125
     126/****************************************************************************
     127****************************************************************************/
     128
     129bool driver_info_ctr_to_info8(struct spoolss_AddDriverInfoCtr *r,
     130                              struct spoolss_DriverInfo8 *_info8)
     131{
     132        struct spoolss_DriverInfo8 info8;
     133
     134        ZERO_STRUCT(info8);
     135
     136        switch (r->level) {
     137        case 3:
     138                info8.version           = r->info.info3->version;
     139                info8.driver_name       = r->info.info3->driver_name;
     140                info8.architecture      = r->info.info3->architecture;
     141                info8.driver_path       = r->info.info3->driver_path;
     142                info8.data_file         = r->info.info3->data_file;
     143                info8.config_file       = r->info.info3->config_file;
     144                info8.help_file         = r->info.info3->help_file;
     145                info8.monitor_name      = r->info.info3->monitor_name;
     146                info8.default_datatype  = r->info.info3->default_datatype;
     147                if (r->info.info3->dependent_files && r->info.info3->dependent_files->string) {
     148                        info8.dependent_files   = r->info.info3->dependent_files->string;
     149                }
     150                break;
     151        case 6:
     152                info8.version           = r->info.info6->version;
     153                info8.driver_name       = r->info.info6->driver_name;
     154                info8.architecture      = r->info.info6->architecture;
     155                info8.driver_path       = r->info.info6->driver_path;
     156                info8.data_file         = r->info.info6->data_file;
     157                info8.config_file       = r->info.info6->config_file;
     158                info8.help_file         = r->info.info6->help_file;
     159                info8.monitor_name      = r->info.info6->monitor_name;
     160                info8.default_datatype  = r->info.info6->default_datatype;
     161                if (r->info.info6->dependent_files && r->info.info6->dependent_files->string) {
     162                        info8.dependent_files   = r->info.info6->dependent_files->string;
     163                }
     164                info8.driver_date       = r->info.info6->driver_date;
     165                info8.driver_version    = r->info.info6->driver_version;
     166                info8.manufacturer_name = r->info.info6->manufacturer_name;
     167                info8.manufacturer_url  = r->info.info6->manufacturer_url;
     168                info8.hardware_id       = r->info.info6->hardware_id;
     169                info8.provider          = r->info.info6->provider;
     170                break;
     171        case 8:
     172                info8.version           = r->info.info8->version;
     173                info8.driver_name       = r->info.info8->driver_name;
     174                info8.architecture      = r->info.info8->architecture;
     175                info8.driver_path       = r->info.info8->driver_path;
     176                info8.data_file         = r->info.info8->data_file;
     177                info8.config_file       = r->info.info8->config_file;
     178                info8.help_file         = r->info.info8->help_file;
     179                info8.monitor_name      = r->info.info8->monitor_name;
     180                info8.default_datatype  = r->info.info8->default_datatype;
     181                if (r->info.info8->dependent_files && r->info.info8->dependent_files->string) {
     182                        info8.dependent_files   = r->info.info8->dependent_files->string;
     183                }
     184                if (r->info.info8->previous_names && r->info.info8->previous_names->string) {
     185                        info8.previous_names    = r->info.info8->previous_names->string;
     186                }
     187                info8.driver_date       = r->info.info8->driver_date;
     188                info8.driver_version    = r->info.info8->driver_version;
     189                info8.manufacturer_name = r->info.info8->manufacturer_name;
     190                info8.manufacturer_url  = r->info.info8->manufacturer_url;
     191                info8.hardware_id       = r->info.info8->hardware_id;
     192                info8.provider          = r->info.info8->provider;
     193                info8.print_processor   = r->info.info8->print_processor;
     194                info8.vendor_setup      = r->info.info8->vendor_setup;
     195                if (r->info.info8->color_profiles && r->info.info8->color_profiles->string) {
     196                        info8.color_profiles = r->info.info8->color_profiles->string;
     197                }
     198                info8.inf_path          = r->info.info8->inf_path;
     199                info8.printer_driver_attributes = r->info.info8->printer_driver_attributes;
     200                if (r->info.info8->core_driver_dependencies && r->info.info8->core_driver_dependencies->string) {
     201                        info8.core_driver_dependencies = r->info.info8->core_driver_dependencies->string;
     202                }
     203                info8.min_inbox_driver_ver_date = r->info.info8->min_inbox_driver_ver_date;
     204                info8.min_inbox_driver_ver_version = r->info.info8->min_inbox_driver_ver_version;
     205                break;
     206        default:
     207                return false;
     208        }
     209
     210        *_info8 = info8;
     211
     212        return true;
     213}
     214
     215/****************************************************************************
     216 Create and allocate a default devicemode.
     217****************************************************************************/
     218
     219WERROR spoolss_create_default_devmode(TALLOC_CTX *mem_ctx,
     220                                      const char *devicename,
     221                                      struct spoolss_DeviceMode **devmode)
     222{
     223        struct spoolss_DeviceMode *dm;
     224        char *dname;
     225
     226        dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
     227        if (dm == NULL) {
     228                return WERR_NOMEM;
     229        }
     230
     231        dname = talloc_asprintf(dm, "%s", devicename);
     232        if (dname == NULL) {
     233                return WERR_NOMEM;
     234        }
     235        if (strlen(dname) > MAXDEVICENAME) {
     236                dname[MAXDEVICENAME] = '\0';
     237        }
     238        dm->devicename = dname;
     239
     240        dm->formname = talloc_strdup(dm, "Letter");
     241        if (dm->formname == NULL) {
     242                return WERR_NOMEM;
     243        }
     244
     245        dm->specversion          = DMSPEC_NT4_AND_ABOVE;
     246        dm->driverversion        = 0x0400;
     247        dm->size                 = 0x00DC;
     248        dm->__driverextra_length = 0;
     249        dm->fields               = DEVMODE_FORMNAME |
     250                                   DEVMODE_TTOPTION |
     251                                   DEVMODE_PRINTQUALITY |
     252                                   DEVMODE_DEFAULTSOURCE |
     253                                   DEVMODE_COPIES |
     254                                   DEVMODE_SCALE |
     255                                   DEVMODE_PAPERSIZE |
     256                                   DEVMODE_ORIENTATION;
     257        dm->orientation          = DMORIENT_PORTRAIT;
     258        dm->papersize            = DMPAPER_LETTER;
     259        dm->paperlength          = 0;
     260        dm->paperwidth           = 0;
     261        dm->scale                = 0x64;
     262        dm->copies               = 1;
     263        dm->defaultsource        = DMBIN_FORMSOURCE;
     264        dm->printquality         = DMRES_HIGH;           /* 0x0258 */
     265        dm->color                = DMRES_MONOCHROME;
     266        dm->duplex               = DMDUP_SIMPLEX;
     267        dm->yresolution          = 0;
     268        dm->ttoption             = DMTT_SUBDEV;
     269        dm->collate              = DMCOLLATE_FALSE;
     270        dm->icmmethod            = 0;
     271        dm->icmintent            = 0;
     272        dm->mediatype            = 0;
     273        dm->dithertype           = 0;
     274
     275        dm->logpixels            = 0;
     276        dm->bitsperpel           = 0;
     277        dm->pelswidth            = 0;
     278        dm->pelsheight           = 0;
     279        dm->displayflags         = 0;
     280        dm->displayfrequency     = 0;
     281        dm->reserved1            = 0;
     282        dm->reserved2            = 0;
     283        dm->panningwidth         = 0;
     284        dm->panningheight        = 0;
     285
     286        dm->driverextra_data.data = NULL;
     287        dm->driverextra_data.length = 0;
     288
     289        *devmode = dm;
     290        return WERR_OK;
     291}
     292
     293WERROR spoolss_create_default_secdesc(TALLOC_CTX *mem_ctx,
     294                                      struct spoolss_security_descriptor **secdesc)
     295{
     296        struct security_ace ace[7];     /* max number of ace entries */
     297        int i = 0;
     298        uint32_t sa;
     299        struct security_acl *psa = NULL;
     300        struct security_descriptor *psd = NULL;
     301        struct dom_sid adm_sid;
     302        size_t sd_size;
     303
     304        /* Create an ACE where Everyone is allowed to print */
     305
     306        sa = PRINTER_ACE_PRINT;
     307        init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
     308                     sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
     309
     310        /* Add the domain admins group if we are a DC */
     311
     312        if ( IS_DC ) {
     313                struct dom_sid domadmins_sid;
     314
     315                sid_compose(&domadmins_sid, get_global_sam_sid(),
     316                            DOMAIN_RID_ADMINS);
     317
     318                sa = PRINTER_ACE_FULL_CONTROL;
     319                init_sec_ace(&ace[i++], &domadmins_sid,
     320                        SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
     321                        SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
     322                init_sec_ace(&ace[i++], &domadmins_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
     323                        sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
     324        }
     325        else if (secrets_fetch_domain_sid(lp_workgroup(), &adm_sid)) {
     326                sid_append_rid(&adm_sid, DOMAIN_RID_ADMINISTRATOR);
     327
     328                sa = PRINTER_ACE_FULL_CONTROL;
     329                init_sec_ace(&ace[i++], &adm_sid,
     330                        SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
     331                        SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
     332                init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
     333                        sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
     334        }
     335
     336        /* add BUILTIN\Administrators as FULL CONTROL */
     337
     338        sa = PRINTER_ACE_FULL_CONTROL;
     339        init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
     340                SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
     341                SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
     342        init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
     343                SEC_ACE_TYPE_ACCESS_ALLOWED,
     344                sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
     345
     346        /* add BUILTIN\Print Operators as FULL CONTROL */
     347
     348        sa = PRINTER_ACE_FULL_CONTROL;
     349        init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
     350                SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
     351                SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
     352        init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
     353                SEC_ACE_TYPE_ACCESS_ALLOWED,
     354                sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
     355
     356        /* Make the security descriptor owned by the BUILTIN\Administrators */
     357
     358        /* The ACL revision number in rpc_secdesc.h differs from the one
     359           created by NT when setting ACE entries in printer
     360           descriptors.  NT4 complains about the property being edited by a
     361           NT5 machine. */
     362
     363        if ((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) != NULL) {
     364                psd = make_sec_desc(mem_ctx,
     365                                    SD_REVISION,
     366                                    SEC_DESC_SELF_RELATIVE,
     367                                    &global_sid_Builtin_Administrators,
     368                                    &global_sid_Builtin_Administrators,
     369                                    NULL,
     370                                    psa,
     371                                    &sd_size);
     372        }
     373
     374        if (psd == NULL) {
     375                DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
     376                return WERR_NOMEM;
     377        }
     378
     379        DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
     380                 (unsigned int)sd_size));
     381
     382        *secdesc = psd;
     383
     384        return WERR_OK;
     385}
  • vendor/current/source3/rpc_client/rpc_transport_np.c

    r427 r740  
    1919
    2020#include "includes.h"
     21#include "../lib/util/tevent_ntstatus.h"
     22#include "rpc_client/rpc_transport.h"
     23#include "libsmb/cli_np_tstream.h"
    2124
    2225#undef DBGC_CLASS
    2326#define DBGC_CLASS DBGC_RPC_CLI
    2427
    25 struct rpc_transport_np_state {
    26         struct cli_state *cli;
    27         const char *pipe_name;
    28         uint16_t fnum;
    29 };
    30 
    31 static bool rpc_np_is_connected(void *priv)
    32 {
    33         struct rpc_transport_np_state *np_transport = talloc_get_type_abort(
    34                 priv, struct rpc_transport_np_state);
    35         bool ok;
    36 
    37         if (np_transport->cli == NULL) {
    38                 return false;
    39         }
    40 
    41         ok = cli_state_is_connected(np_transport->cli);
    42         if (!ok) {
    43                 np_transport->cli = NULL;
    44                 return false;
    45         }
    46 
    47         return true;
    48 }
    49 
    50 static unsigned int rpc_np_set_timeout(void *priv, unsigned int timeout)
    51 {
    52         struct rpc_transport_np_state *np_transport = talloc_get_type_abort(
    53                 priv, struct rpc_transport_np_state);
    54         bool ok;
    55 
    56         if (np_transport->cli == NULL) {
    57                 return false;
    58         }
    59 
    60         ok = rpc_np_is_connected(np_transport);
    61         if (!ok) {
    62                 return 0;
    63         }
    64 
    65         return cli_set_timeout(np_transport->cli, timeout);
    66 }
    67 
    68 static int rpc_transport_np_state_destructor(struct rpc_transport_np_state *s)
    69 {
    70         if (!rpc_np_is_connected(s)) {
    71                 DEBUG(10, ("socket was closed, no need to send close request.\n"));
    72                 return 0;
    73         }
    74 
    75         /* TODO: do not use a sync call with a destructor!!! */
    76         if (!NT_STATUS_IS_OK(cli_close(s->cli, s->fnum))) {
    77                 DEBUG(1, ("rpc_transport_np_state_destructor: cli_close "
    78                           "failed on pipe %s. Error was %s\n", s->pipe_name,
    79                           cli_errstr(s->cli)));
    80         }
    81         DEBUG(10, ("rpc_pipe_destructor: closed %s\n", s->pipe_name));
    82         /*
    83          * We can't do much on failure
    84          */
    85         return 0;
    86 }
    87 
    88 struct rpc_np_write_state {
    89         struct rpc_transport_np_state *np_transport;
    90         size_t size;
    91         size_t written;
    92 };
    93 
    94 static void rpc_np_write_done(struct tevent_req *subreq);
    95 
    96 static struct tevent_req *rpc_np_write_send(TALLOC_CTX *mem_ctx,
    97                                             struct event_context *ev,
    98                                             const uint8_t *data, size_t size,
    99                                             void *priv)
    100 {
    101         struct rpc_transport_np_state *np_transport = talloc_get_type_abort(
    102                 priv, struct rpc_transport_np_state);
    103         struct tevent_req *req, *subreq;
    104         struct rpc_np_write_state *state;
    105         bool ok;
    106 
    107         req = tevent_req_create(mem_ctx, &state, struct rpc_np_write_state);
    108         if (req == NULL) {
    109                 return NULL;
    110         }
    111 
    112         ok = rpc_np_is_connected(np_transport);
    113         if (!ok) {
    114                 tevent_req_nterror(req, NT_STATUS_CONNECTION_INVALID);
    115                 return tevent_req_post(req, ev);
    116         }
    117 
    118         state->np_transport = np_transport;
    119         state->size = size;
    120 
    121 
    122         subreq = cli_write_andx_send(mem_ctx, ev, np_transport->cli,
    123                                      np_transport->fnum,
    124                                      8, /* 8 means message mode. */
    125                                      data, 0, size);
    126         if (tevent_req_nomem(subreq, req)) {
    127                 return tevent_req_post(req, ev);
    128         }
    129         tevent_req_set_callback(subreq, rpc_np_write_done, req);
    130         return req;
    131 }
    132 
    133 static void rpc_np_write_done(struct tevent_req *subreq)
    134 {
    135         struct tevent_req *req = tevent_req_callback_data(
    136                 subreq, struct tevent_req);
    137         struct rpc_np_write_state *state = tevent_req_data(
    138                 req, struct rpc_np_write_state);
    139         NTSTATUS status;
    140 
    141         status = cli_write_andx_recv(subreq, &state->written);
    142         TALLOC_FREE(subreq);
    143         if (!NT_STATUS_IS_OK(status)) {
    144                 state->np_transport->cli = NULL;
    145                 tevent_req_nterror(req, status);
    146                 return;
    147         }
    148         tevent_req_done(req);
    149 }
    150 
    151 static NTSTATUS rpc_np_write_recv(struct tevent_req *req, ssize_t *pwritten)
    152 {
    153         struct rpc_np_write_state *state = tevent_req_data(
    154                 req, struct rpc_np_write_state);
    155         NTSTATUS status;
    156 
    157         if (tevent_req_is_nterror(req, &status)) {
    158                 return status;
    159         }
    160         *pwritten = state->written;
    161         return NT_STATUS_OK;
    162 }
    163 
    164 struct rpc_np_read_state {
    165         struct rpc_transport_np_state *np_transport;
    166         uint8_t *data;
    167         size_t size;
    168         ssize_t received;
    169 };
    170 
    171 static void rpc_np_read_done(struct tevent_req *subreq);
    172 
    173 static struct tevent_req *rpc_np_read_send(TALLOC_CTX *mem_ctx,
    174                                            struct event_context *ev,
    175                                            uint8_t *data, size_t size,
    176                                            void *priv)
    177 {
    178         struct rpc_transport_np_state *np_transport = talloc_get_type_abort(
    179                 priv, struct rpc_transport_np_state);
    180         struct tevent_req *req, *subreq;
    181         struct rpc_np_read_state *state;
    182         bool ok;
    183 
    184         req = tevent_req_create(mem_ctx, &state, struct rpc_np_read_state);
    185         if (req == NULL) {
    186                 return NULL;
    187         }
    188 
    189         ok = rpc_np_is_connected(np_transport);
    190         if (!ok) {
    191                 tevent_req_nterror(req, NT_STATUS_CONNECTION_INVALID);
    192                 return tevent_req_post(req, ev);
    193         }
    194 
    195         state->np_transport = np_transport;
    196         state->data = data;
    197         state->size = size;
    198 
    199         subreq = cli_read_andx_send(mem_ctx, ev, np_transport->cli,
    200                                     np_transport->fnum, 0, size);
    201         if (subreq == NULL) {
    202                 goto fail;
    203         }
    204         tevent_req_set_callback(subreq, rpc_np_read_done, req);
    205         return req;
    206  fail:
    207         TALLOC_FREE(req);
    208         return NULL;
    209 }
    210 
    211 static void rpc_np_read_done(struct tevent_req *subreq)
    212 {
    213         struct tevent_req *req = tevent_req_callback_data(
    214                 subreq, struct tevent_req);
    215         struct rpc_np_read_state *state = tevent_req_data(
    216                 req, struct rpc_np_read_state);
    217         NTSTATUS status;
    218         uint8_t *rcvbuf;
    219 
    220         /* We must free subreq in this function as there is
    221            a timer event attached to it. */
    222 
    223         status = cli_read_andx_recv(subreq, &state->received, &rcvbuf);
    224         /*
    225          * We can't TALLOC_FREE(subreq) as usual here, as rcvbuf still is a
    226          * child of that.
    227          */
    228         if (NT_STATUS_EQUAL(status, NT_STATUS_BUFFER_TOO_SMALL)) {
    229                 status = NT_STATUS_OK;
    230         }
    231         if (!NT_STATUS_IS_OK(status)) {
    232                 TALLOC_FREE(subreq);
    233                 state->np_transport->cli = NULL;
    234                 tevent_req_nterror(req, status);
    235                 return;
    236         }
    237 
    238         if (state->received > state->size) {
    239                 TALLOC_FREE(subreq);
    240                 state->np_transport->cli = NULL;
    241                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
    242                 return;
    243         }
    244 
    245         if (state->received == 0) {
    246                 TALLOC_FREE(subreq);
    247                 state->np_transport->cli = NULL;
    248                 tevent_req_nterror(req, NT_STATUS_PIPE_BROKEN);
    249                 return;
    250         }
    251 
    252         memcpy(state->data, rcvbuf, state->received);
    253         TALLOC_FREE(subreq);
    254         tevent_req_done(req);
    255 }
    256 
    257 static NTSTATUS rpc_np_read_recv(struct tevent_req *req, ssize_t *preceived)
    258 {
    259         struct rpc_np_read_state *state = tevent_req_data(
    260                 req, struct rpc_np_read_state);
    261         NTSTATUS status;
    262 
    263         if (tevent_req_is_nterror(req, &status)) {
    264                 return status;
    265         }
    266         *preceived = state->received;
    267         return NT_STATUS_OK;
    268 }
    269 
    270 struct rpc_np_trans_state {
    271         struct rpc_transport_np_state *np_transport;
    272         uint16_t setup[2];
    273         uint32_t max_rdata_len;
    274         uint8_t *rdata;
    275         uint32_t rdata_len;
    276 };
    277 
    278 static void rpc_np_trans_done(struct tevent_req *subreq);
    279 
    280 static struct tevent_req *rpc_np_trans_send(TALLOC_CTX *mem_ctx,
    281                                             struct event_context *ev,
    282                                             uint8_t *data, size_t data_len,
    283                                             uint32_t max_rdata_len,
    284                                             void *priv)
    285 {
    286         struct rpc_transport_np_state *np_transport = talloc_get_type_abort(
    287                 priv, struct rpc_transport_np_state);
    288         struct tevent_req *req, *subreq;
    289         struct rpc_np_trans_state *state;
    290         bool ok;
    291 
    292         req = tevent_req_create(mem_ctx, &state, struct rpc_np_trans_state);
    293         if (req == NULL) {
    294                 return NULL;
    295         }
    296 
    297         ok = rpc_np_is_connected(np_transport);
    298         if (!ok) {
    299                 tevent_req_nterror(req, NT_STATUS_CONNECTION_INVALID);
    300                 return tevent_req_post(req, ev);
    301         }
    302 
    303         state->np_transport = np_transport;
    304         state->max_rdata_len = max_rdata_len;
    305 
    306         SSVAL(state->setup+0, 0, TRANSACT_DCERPCCMD);
    307         SSVAL(state->setup+1, 0, np_transport->fnum);
    308 
    309         subreq = cli_trans_send(
    310                 state, ev, np_transport->cli, SMBtrans,
    311                 "\\PIPE\\", 0, 0, 0, state->setup, 2, 0,
    312                 NULL, 0, 0, data, data_len, max_rdata_len);
    313         if (subreq == NULL) {
    314                 goto fail;
    315         }
    316         tevent_req_set_callback(subreq, rpc_np_trans_done, req);
    317         return req;
    318 
    319  fail:
    320         TALLOC_FREE(req);
    321         return NULL;
    322 }
    323 
    324 static void rpc_np_trans_done(struct tevent_req *subreq)
    325 {
    326         struct tevent_req *req = tevent_req_callback_data(
    327                 subreq, struct tevent_req);
    328         struct rpc_np_trans_state *state = tevent_req_data(
    329                 req, struct rpc_np_trans_state);
    330         NTSTATUS status;
    331 
    332         status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL,
    333                                 &state->rdata, &state->rdata_len);
    334         TALLOC_FREE(subreq);
    335         if (NT_STATUS_EQUAL(status, NT_STATUS_BUFFER_TOO_SMALL)) {
    336                 status = NT_STATUS_OK;
    337         }
    338         if (!NT_STATUS_IS_OK(status)) {
    339                 state->np_transport->cli = NULL;
    340                 tevent_req_nterror(req, status);
    341                 return;
    342         }
    343 
    344         if (state->rdata_len > state->max_rdata_len) {
    345                 state->np_transport->cli = NULL;
    346                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
    347                 return;
    348         }
    349 
    350         if (state->rdata_len == 0) {
    351                 state->np_transport->cli = NULL;
    352                 tevent_req_nterror(req, NT_STATUS_PIPE_BROKEN);
    353                 return;
    354         }
    355 
    356         tevent_req_done(req);
    357 }
    358 
    359 static NTSTATUS rpc_np_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
    360                                   uint8_t **prdata, uint32_t *prdata_len)
    361 {
    362         struct rpc_np_trans_state *state = tevent_req_data(
    363                 req, struct rpc_np_trans_state);
    364         NTSTATUS status;
    365 
    366         if (tevent_req_is_nterror(req, &status)) {
    367                 return status;
    368         }
    369         *prdata = talloc_move(mem_ctx, &state->rdata);
    370         *prdata_len = state->rdata_len;
    371         return NT_STATUS_OK;
    372 }
    373 
    37428struct rpc_transport_np_init_state {
    37529        struct rpc_cli_transport *transport;
    376         struct rpc_transport_np_state *transport_np;
    37730};
    37831
     
    38437                                              const struct ndr_syntax_id *abstract_syntax)
    38538{
    386         struct tevent_req *req, *subreq;
     39        struct tevent_req *req;
    38740        struct rpc_transport_np_init_state *state;
    388         bool ok;
     41        const char *pipe_name;
     42        struct tevent_req *subreq;
    38943
    39044        req = tevent_req_create(mem_ctx, &state,
     
    39448        }
    39549
    396         ok = cli_state_is_connected(cli);
    397         if (!ok) {
    398                 tevent_req_nterror(req, NT_STATUS_CONNECTION_INVALID);
     50        pipe_name = get_pipe_name_from_syntax(state, abstract_syntax);
     51        if (tevent_req_nomem(pipe_name, req)) {
    39952                return tevent_req_post(req, ev);
    40053        }
    40154
    402         state->transport = talloc(state, struct rpc_cli_transport);
    403         if (tevent_req_nomem(state->transport, req)) {
    404                 return tevent_req_post(req, ev);
    405         }
    406         state->transport_np = talloc(state->transport,
    407                                      struct rpc_transport_np_state);
    408         if (tevent_req_nomem(state->transport_np, req)) {
    409                 return tevent_req_post(req, ev);
    410         }
    411         state->transport->priv = state->transport_np;
    412 
    413         state->transport_np->pipe_name = get_pipe_name_from_syntax(
    414                 state->transport_np, abstract_syntax);
    415         state->transport_np->cli = cli;
    416 
    417         subreq = cli_ntcreate_send(
    418                 state, ev, cli, state->transport_np->pipe_name, 0,
    419                 DESIRED_ACCESS_PIPE, 0, FILE_SHARE_READ|FILE_SHARE_WRITE,
    420                 FILE_OPEN, 0, 0);
     55        subreq = tstream_cli_np_open_send(state, ev, cli, pipe_name);
    42156        if (tevent_req_nomem(subreq, req)) {
    42257                return tevent_req_post(req, ev);
    42358        }
    424         tevent_req_set_callback(subreq, rpc_transport_np_init_pipe_open,
    425                                 req);
     59        tevent_req_set_callback(subreq, rpc_transport_np_init_pipe_open, req);
     60
    42661        return req;
    42762}
     
    43469                req, struct rpc_transport_np_init_state);
    43570        NTSTATUS status;
     71        struct tstream_context *stream;
    43672
    437         status = cli_ntcreate_recv(subreq, &state->transport_np->fnum);
     73        status = tstream_cli_np_open_recv(subreq, state, &stream);
    43874        TALLOC_FREE(subreq);
    43975        if (!NT_STATUS_IS_OK(status)) {
     
    44278        }
    44379
    444         talloc_set_destructor(state->transport_np,
    445                               rpc_transport_np_state_destructor);
     80        status = rpc_transport_tstream_init(state,
     81                                            &stream,
     82                                            &state->transport);
     83        if (!NT_STATUS_IS_OK(status)) {
     84                tevent_req_nterror(req, status);
     85                return;
     86        }
     87
    44688        tevent_req_done(req);
    44789}
     
    458100                return status;
    459101        }
    460 
    461         state->transport->write_send = rpc_np_write_send;
    462         state->transport->write_recv = rpc_np_write_recv;
    463         state->transport->read_send = rpc_np_read_send;
    464         state->transport->read_recv = rpc_np_read_recv;
    465         state->transport->trans_send = rpc_np_trans_send;
    466         state->transport->trans_recv = rpc_np_trans_recv;
    467         state->transport->is_connected = rpc_np_is_connected;
    468         state->transport->set_timeout = rpc_np_set_timeout;
    469102
    470103        *presult = talloc_move(mem_ctx, &state->transport);
     
    503136        return status;
    504137}
    505 
    506 struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p)
    507 {
    508         struct rpc_transport_np_state *state = talloc_get_type(
    509                 p->transport->priv, struct rpc_transport_np_state);
    510 
    511         if (state == NULL) {
    512                 return NULL;
    513         }
    514         return state->cli;
    515 }
  • vendor/current/source3/rpc_client/rpc_transport_sock.c

    r427 r740  
    1919
    2020#include "includes.h"
     21#include "../lib/tsocket/tsocket.h"
     22#include "rpc_client/rpc_transport.h"
    2123
    2224#undef DBGC_CLASS
    2325#define DBGC_CLASS DBGC_RPC_CLI
    24 
    25 struct rpc_transport_sock_state {
    26         int fd;
    27         int timeout;
    28 };
    29 
    30 static void rpc_sock_disconnect(struct rpc_transport_sock_state *s)
    31 {
    32         if (s->fd != -1) {
    33                 close(s->fd);
    34                 s->fd = -1;
    35         }
    36 }
    37 
    38 static int rpc_transport_sock_state_destructor(struct rpc_transport_sock_state *s)
    39 {
    40         rpc_sock_disconnect(s);
    41         return 0;
    42 }
    43 
    44 static bool rpc_sock_is_connected(void *priv)
    45 {
    46         struct rpc_transport_sock_state *sock_transp = talloc_get_type_abort(
    47                 priv, struct rpc_transport_sock_state);
    48 
    49         if (sock_transp->fd == -1) {
    50                 return false;
    51         }
    52 
    53         return true;
    54 }
    55 
    56 static unsigned int rpc_sock_set_timeout(void *priv, unsigned int timeout)
    57 {
    58         struct rpc_transport_sock_state *sock_transp = talloc_get_type_abort(
    59                 priv, struct rpc_transport_sock_state);
    60         int orig_timeout;
    61         bool ok;
    62 
    63         ok = rpc_sock_is_connected(sock_transp);
    64         if (!ok) {
    65                 return 0;
    66         }
    67 
    68         orig_timeout = sock_transp->timeout;
    69 
    70         sock_transp->timeout = timeout;
    71 
    72         return orig_timeout;
    73 }
    74 
    75 struct rpc_sock_read_state {
    76         struct rpc_transport_sock_state *transp;
    77         ssize_t received;
    78 };
    79 
    80 static void rpc_sock_read_done(struct tevent_req *subreq);
    81 
    82 static struct tevent_req *rpc_sock_read_send(TALLOC_CTX *mem_ctx,
    83                                              struct event_context *ev,
    84                                              uint8_t *data, size_t size,
    85                                              void *priv)
    86 {
    87         struct rpc_transport_sock_state *sock_transp = talloc_get_type_abort(
    88                 priv, struct rpc_transport_sock_state);
    89         struct tevent_req *req, *subreq;
    90         struct rpc_sock_read_state *state;
    91         struct timeval endtime;
    92 
    93         req = tevent_req_create(mem_ctx, &state, struct rpc_sock_read_state);
    94         if (req == NULL) {
    95                 return NULL;
    96         }
    97         if (!rpc_sock_is_connected(sock_transp)) {
    98                 tevent_req_nterror(req, NT_STATUS_CONNECTION_INVALID);
    99                 return tevent_req_post(req, ev);
    100         }
    101         state->transp = sock_transp;
    102         endtime = timeval_current_ofs(0, sock_transp->timeout * 1000);
    103         subreq = async_recv_send(state, ev, sock_transp->fd, data, size, 0);
    104         if (subreq == NULL) {
    105                 goto fail;
    106         }
    107 
    108         if (!tevent_req_set_endtime(subreq, ev, endtime)) {
    109                 goto fail;
    110         }
    111 
    112         tevent_req_set_callback(subreq, rpc_sock_read_done, req);
    113         return req;
    114  fail:
    115         TALLOC_FREE(req);
    116         return NULL;
    117 }
    118 
    119 static void rpc_sock_read_done(struct tevent_req *subreq)
    120 {
    121         struct tevent_req *req = tevent_req_callback_data(
    122                 subreq, struct tevent_req);
    123         struct rpc_sock_read_state *state = tevent_req_data(
    124                 req, struct rpc_sock_read_state);
    125         int err;
    126 
    127         /* We must free subreq in this function as there is
    128           a timer event attached to it. */
    129 
    130         state->received = async_recv_recv(subreq, &err);
    131 
    132         if (state->received == -1) {
    133                 TALLOC_FREE(subreq);
    134                 rpc_sock_disconnect(state->transp);
    135                 tevent_req_nterror(req, map_nt_error_from_unix(err));
    136                 return;
    137         }
    138         TALLOC_FREE(subreq);
    139         tevent_req_done(req);
    140 }
    141 
    142 static NTSTATUS rpc_sock_read_recv(struct tevent_req *req, ssize_t *preceived)
    143 {
    144         struct rpc_sock_read_state *state = tevent_req_data(
    145                 req, struct rpc_sock_read_state);
    146         NTSTATUS status;
    147 
    148         if (tevent_req_is_nterror(req, &status)) {
    149                 return status;
    150         }
    151         *preceived = state->received;
    152         return NT_STATUS_OK;
    153 }
    154 
    155 struct rpc_sock_write_state {
    156         struct rpc_transport_sock_state *transp;
    157         ssize_t sent;
    158 };
    159 
    160 static void rpc_sock_write_done(struct tevent_req *subreq);
    161 
    162 static struct tevent_req *rpc_sock_write_send(TALLOC_CTX *mem_ctx,
    163                                               struct event_context *ev,
    164                                               const uint8_t *data, size_t size,
    165                                               void *priv)
    166 {
    167         struct rpc_transport_sock_state *sock_transp = talloc_get_type_abort(
    168                 priv, struct rpc_transport_sock_state);
    169         struct tevent_req *req, *subreq;
    170         struct rpc_sock_write_state *state;
    171         struct timeval endtime;
    172 
    173         req = tevent_req_create(mem_ctx, &state, struct rpc_sock_write_state);
    174         if (req == NULL) {
    175                 return NULL;
    176         }
    177         if (!rpc_sock_is_connected(sock_transp)) {
    178                 tevent_req_nterror(req, NT_STATUS_CONNECTION_INVALID);
    179                 return tevent_req_post(req, ev);
    180         }
    181         state->transp = sock_transp;
    182         endtime = timeval_current_ofs(0, sock_transp->timeout * 1000);
    183         subreq = async_send_send(state, ev, sock_transp->fd, data, size, 0);
    184         if (subreq == NULL) {
    185                 goto fail;
    186         }
    187 
    188         if (!tevent_req_set_endtime(subreq, ev, endtime)) {
    189                 goto fail;
    190         }
    191 
    192         tevent_req_set_callback(subreq, rpc_sock_write_done, req);
    193         return req;
    194  fail:
    195         TALLOC_FREE(req);
    196         return NULL;
    197 }
    198 
    199 static void rpc_sock_write_done(struct tevent_req *subreq)
    200 {
    201         struct tevent_req *req = tevent_req_callback_data(
    202                 subreq, struct tevent_req);
    203         struct rpc_sock_write_state *state = tevent_req_data(
    204                 req, struct rpc_sock_write_state);
    205         int err;
    206 
    207         /* We must free subreq in this function as there is
    208           a timer event attached to it. */
    209 
    210         state->sent = async_send_recv(subreq, &err);
    211 
    212         if (state->sent == -1) {
    213                 TALLOC_FREE(subreq);
    214                 rpc_sock_disconnect(state->transp);
    215                 tevent_req_nterror(req, map_nt_error_from_unix(err));
    216                 return;
    217         }
    218         TALLOC_FREE(subreq);
    219         tevent_req_done(req);
    220 }
    221 
    222 static NTSTATUS rpc_sock_write_recv(struct tevent_req *req, ssize_t *psent)
    223 {
    224         struct rpc_sock_write_state *state = tevent_req_data(
    225                 req, struct rpc_sock_write_state);
    226         NTSTATUS status;
    227 
    228         if (tevent_req_is_nterror(req, &status)) {
    229                 return status;
    230         }
    231         *psent = state->sent;
    232         return NT_STATUS_OK;
    233 }
    23426
    23527NTSTATUS rpc_transport_sock_init(TALLOC_CTX *mem_ctx, int fd,
     
    23729{
    23830        struct rpc_cli_transport *result;
    239         struct rpc_transport_sock_state *state;
     31        struct tstream_context *stream;
     32        int ret;
     33        NTSTATUS status;
    24034
    241         result = talloc(mem_ctx, struct rpc_cli_transport);
    242         if (result == NULL) {
    243                 return NT_STATUS_NO_MEMORY;
     35        set_blocking(fd, false);
     36
     37        ret = tstream_bsd_existing_socket(mem_ctx, fd, &stream);
     38        if (ret != 0) {
     39                status = map_nt_error_from_unix(errno);
     40                return status;
    24441        }
    245         state = talloc(result, struct rpc_transport_sock_state);
    246         if (state == NULL) {
    247                 TALLOC_FREE(result);
    248                 return NT_STATUS_NO_MEMORY;
     42
     43        status = rpc_transport_tstream_init(mem_ctx,
     44                                            &stream,
     45                                            &result);
     46        if (!NT_STATUS_IS_OK(status)) {
     47                TALLOC_FREE(stream);
     48                return status;
    24949        }
    250         result->priv = state;
    251 
    252         state->fd = fd;
    253         state->timeout = 10000; /* 10 seconds. */
    254         talloc_set_destructor(state, rpc_transport_sock_state_destructor);
    255 
    256         result->trans_send = NULL;
    257         result->trans_recv = NULL;
    258         result->write_send = rpc_sock_write_send;
    259         result->write_recv = rpc_sock_write_recv;
    260         result->read_send = rpc_sock_read_send;
    261         result->read_recv = rpc_sock_read_recv;
    262         result->is_connected = rpc_sock_is_connected;
    263         result->set_timeout = rpc_sock_set_timeout;
    26450
    26551        *presult = result;
Note: See TracChangeset for help on using the changeset viewer.