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

Samba Server: update vendor to version 4.4.3

Location:
vendor/current/source3/rpc_client
Files:
21 edited

Legend:

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

    r860 r988  
    8282NTSTATUS rpccli_lsa_open_policy(struct rpc_pipe_client *cli,
    8383                                TALLOC_CTX *mem_ctx,
    84                                 bool sec_qos, uint32 des_access,
     84                                bool sec_qos, uint32_t des_access,
    8585                                struct policy_handle *pol)
    8686{
     
    141141NTSTATUS rpccli_lsa_open_policy2(struct rpc_pipe_client *cli,
    142142                                 TALLOC_CTX *mem_ctx, bool sec_qos,
    143                                  uint32 des_access, struct policy_handle *pol)
     143                                 uint32_t des_access, struct policy_handle *pol)
    144144{
    145145        NTSTATUS status;
     
    190190
    191191        sid_array.num_sids = num_sids;
    192         sid_array.sids = TALLOC_ARRAY(mem_ctx, struct lsa_SidPtr, num_sids);
     192        sid_array.sids = talloc_array(mem_ctx, struct lsa_SidPtr, num_sids);
    193193        if (sid_array.sids == NULL) {
    194194                return NT_STATUS_NO_MEMORY;
     
    317317                                                   dom_name ? dom_name : "");
    318318                        (types)[i] = lsa_names.names[i].sid_type;
    319                         if (((domains)[i] == NULL)) {
     319                        if ((domains)[i] == NULL) {
    320320                                DEBUG(0, ("cli_lsa_lookup_sids_noalloc(): out of memory\n"));
    321321                                *presult = NT_STATUS_UNSUCCESSFUL;
     
    372372
    373373        if (num_sids) {
    374                 if (!(domains = TALLOC_ARRAY(mem_ctx, char *, num_sids))) {
     374                if (!(domains = talloc_array(mem_ctx, char *, num_sids))) {
    375375                        DEBUG(0, ("rpccli_lsa_lookup_sids(): out of memory\n"));
    376376                        status = NT_STATUS_NO_MEMORY;
     
    378378                }
    379379
    380                 if (!(names = TALLOC_ARRAY(mem_ctx, char *, num_sids))) {
     380                if (!(names = talloc_array(mem_ctx, char *, num_sids))) {
    381381                        DEBUG(0, ("rpccli_lsa_lookup_sids(): out of memory\n"));
    382382                        status = NT_STATUS_NO_MEMORY;
     
    384384                }
    385385
    386                 if (!(types = TALLOC_ARRAY(mem_ctx, enum lsa_SidType, num_sids))) {
     386                if (!(types = talloc_array(mem_ctx, enum lsa_SidType, num_sids))) {
    387387                        DEBUG(0, ("rpccli_lsa_lookup_sids(): out of memory\n"));
    388388                        status = NT_STATUS_NO_MEMORY;
     
    580580        ZERO_STRUCT(sid_array3);
    581581
    582         lsa_names = TALLOC_ARRAY(mem_ctx, struct lsa_String, num_names);
     582        lsa_names = talloc_array(mem_ctx, struct lsa_String, num_names);
    583583        if (lsa_names == NULL) {
    584584                return NT_STATUS_NO_MEMORY;
     
    630630
    631631        if (num_names) {
    632                 if (!((*sids = TALLOC_ARRAY(mem_ctx, struct dom_sid, num_names)))) {
     632                if (!((*sids = talloc_array(mem_ctx, struct dom_sid, num_names)))) {
    633633                        DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
    634634                        *presult = NT_STATUS_NO_MEMORY;
     
    636636                }
    637637
    638                 if (!((*types = TALLOC_ARRAY(mem_ctx, enum lsa_SidType, num_names)))) {
     638                if (!((*types = talloc_array(mem_ctx, enum lsa_SidType, num_names)))) {
    639639                        DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
    640640                        *presult = NT_STATUS_NO_MEMORY;
     
    643643
    644644                if (dom_names != NULL) {
    645                         *dom_names = TALLOC_ARRAY(mem_ctx, const char *, num_names);
     645                        *dom_names = talloc_array(mem_ctx, const char *, num_names);
    646646                        if (*dom_names == NULL) {
    647647                                DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
  • vendor/current/source3/rpc_client/cli_lsarpc.h

    r860 r988  
    5555NTSTATUS rpccli_lsa_open_policy(struct rpc_pipe_client *cli,
    5656                                TALLOC_CTX *mem_ctx,
    57                                 bool sec_qos, uint32 des_access,
     57                                bool sec_qos, uint32_t des_access,
    5858                                struct policy_handle *pol);
    5959
     
    8484NTSTATUS rpccli_lsa_open_policy2(struct rpc_pipe_client *cli,
    8585                                 TALLOC_CTX *mem_ctx, bool sec_qos,
    86                                  uint32 des_access, struct policy_handle *pol);
     86                                 uint32_t des_access, struct policy_handle *pol);
    8787
    8888/**
  • vendor/current/source3/rpc_client/cli_netlogon.c

    r860 r988  
    2222
    2323#include "includes.h"
     24#include "system/filesys.h"
     25#include "libsmb/libsmb.h"
    2426#include "rpc_client/rpc_client.h"
     27#include "rpc_client/cli_pipe.h"
    2528#include "../libcli/auth/libcli_auth.h"
     29#include "../libcli/auth/netlogon_creds_cli.h"
    2630#include "../librpc/gen_ndr/ndr_netlogon_c.h"
     31#include "../librpc/gen_ndr/schannel.h"
    2732#include "rpc_client/cli_netlogon.h"
    2833#include "rpc_client/init_netlogon.h"
    2934#include "rpc_client/util_netlogon.h"
    3035#include "../libcli/security/security.h"
    31 
    32 /****************************************************************************
    33  Wrapper function that uses the auth and auth2 calls to set up a NETLOGON
    34  credentials chain. Stores the credentials in the struct dcinfo in the
    35  netlogon pipe struct.
    36 ****************************************************************************/
    37 
    38 NTSTATUS rpccli_netlogon_setup_creds(struct rpc_pipe_client *cli,
    39                                      const char *server_name,
    40                                      const char *domain,
    41                                      const char *clnt_name,
    42                                      const char *machine_account,
    43                                      const unsigned char machine_pwd[16],
    44                                      enum netr_SchannelType sec_chan_type,
    45                                      uint32_t *neg_flags_inout)
    46 {
    47         NTSTATUS status;
    48         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
    49         struct netr_Credential clnt_chal_send;
    50         struct netr_Credential srv_chal_recv;
    51         struct samr_Password password;
    52         bool retried = false;
    53         fstring mach_acct;
    54         uint32_t neg_flags = *neg_flags_inout;
    55         struct dcerpc_binding_handle *b = cli->binding_handle;
    56 
    57         if (!ndr_syntax_id_equal(&cli->abstract_syntax,
    58                                  &ndr_table_netlogon.syntax_id)) {
     36#include "lib/param/param.h"
     37#include "libcli/smb/smbXcli_base.h"
     38#include "dbwrap/dbwrap.h"
     39#include "dbwrap/dbwrap_open.h"
     40#include "util_tdb.h"
     41
     42
     43NTSTATUS rpccli_pre_open_netlogon_creds(void)
     44{
     45        static bool already_open = false;
     46        TALLOC_CTX *frame;
     47        struct loadparm_context *lp_ctx;
     48        char *fname;
     49        struct db_context *global_db;
     50        NTSTATUS status;
     51
     52        if (already_open) {
     53                return NT_STATUS_OK;
     54        }
     55
     56        frame = talloc_stackframe();
     57
     58        lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers());
     59        if (lp_ctx == NULL) {
     60                TALLOC_FREE(frame);
     61                return NT_STATUS_NO_MEMORY;
     62        }
     63
     64        fname = lpcfg_private_db_path(frame, lp_ctx, "netlogon_creds_cli");
     65        if (fname == NULL) {
     66                TALLOC_FREE(frame);
     67                return NT_STATUS_NO_MEMORY;
     68        }
     69
     70        global_db = db_open(talloc_autofree_context(), fname,
     71                            0, TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH,
     72                            O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_2,
     73                            DBWRAP_FLAG_OPTIMIZE_READONLY_ACCESS);
     74        if (global_db == NULL) {
     75                TALLOC_FREE(frame);
     76                return NT_STATUS_NO_MEMORY;
     77        }
     78
     79        status = netlogon_creds_cli_set_global_db(&global_db);
     80        TALLOC_FREE(frame);
     81        if (!NT_STATUS_IS_OK(status)) {
     82                return status;
     83        }
     84
     85        already_open = true;
     86        return NT_STATUS_OK;
     87}
     88
     89NTSTATUS rpccli_create_netlogon_creds(const char *server_computer,
     90                                      const char *server_netbios_domain,
     91                                      const char *client_account,
     92                                      enum netr_SchannelType sec_chan_type,
     93                                      struct messaging_context *msg_ctx,
     94                                      TALLOC_CTX *mem_ctx,
     95                                      struct netlogon_creds_cli_context **netlogon_creds)
     96{
     97        TALLOC_CTX *frame = talloc_stackframe();
     98        struct loadparm_context *lp_ctx;
     99        NTSTATUS status;
     100
     101        status = rpccli_pre_open_netlogon_creds();
     102        if (!NT_STATUS_IS_OK(status)) {
     103                TALLOC_FREE(frame);
     104                return status;
     105        }
     106
     107        lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers());
     108        if (lp_ctx == NULL) {
     109                TALLOC_FREE(frame);
     110                return NT_STATUS_NO_MEMORY;
     111        }
     112        status = netlogon_creds_cli_context_global(lp_ctx,
     113                                                   msg_ctx,
     114                                                   client_account,
     115                                                   sec_chan_type,
     116                                                   server_computer,
     117                                                   server_netbios_domain,
     118                                                   mem_ctx, netlogon_creds);
     119        TALLOC_FREE(frame);
     120        if (!NT_STATUS_IS_OK(status)) {
     121                return status;
     122        }
     123
     124        return NT_STATUS_OK;
     125}
     126
     127NTSTATUS rpccli_create_netlogon_creds_with_creds(struct cli_credentials *creds,
     128                                                 const char *server_computer,
     129                                                 struct messaging_context *msg_ctx,
     130                                                 TALLOC_CTX *mem_ctx,
     131                                                 struct netlogon_creds_cli_context **netlogon_creds)
     132{
     133        enum netr_SchannelType sec_chan_type;
     134        const char *server_netbios_domain;
     135        const char *client_account;
     136
     137        sec_chan_type = cli_credentials_get_secure_channel_type(creds);
     138        if (sec_chan_type == SEC_CHAN_NULL) {
     139                return NT_STATUS_INVALID_PARAMETER_MIX;
     140        }
     141
     142        client_account = cli_credentials_get_username(creds);
     143        server_netbios_domain = cli_credentials_get_domain(creds);
     144
     145        return rpccli_create_netlogon_creds(server_computer,
     146                                            server_netbios_domain,
     147                                            client_account,
     148                                            sec_chan_type,
     149                                            msg_ctx, mem_ctx,
     150                                            netlogon_creds);
     151}
     152
     153NTSTATUS rpccli_setup_netlogon_creds(struct cli_state *cli,
     154                                     enum dcerpc_transport_t transport,
     155                                     struct netlogon_creds_cli_context *netlogon_creds,
     156                                     bool force_reauth,
     157                                     struct samr_Password current_nt_hash,
     158                                     const struct samr_Password *previous_nt_hash)
     159{
     160        TALLOC_CTX *frame = talloc_stackframe();
     161        struct rpc_pipe_client *netlogon_pipe = NULL;
     162        struct netlogon_creds_CredentialState *creds = NULL;
     163        NTSTATUS status;
     164
     165        status = netlogon_creds_cli_get(netlogon_creds,
     166                                        frame, &creds);
     167        if (NT_STATUS_IS_OK(status)) {
     168                const char *action = "using";
     169
     170                if (force_reauth) {
     171                        action = "overwrite";
     172                }
     173
     174                DEBUG(5,("%s: %s cached netlogon_creds cli[%s/%s] to %s\n",
     175                         __FUNCTION__, action,
     176                         creds->account_name, creds->computer_name,
     177                         smbXcli_conn_remote_name(cli->conn)));
     178                if (!force_reauth) {
     179                        TALLOC_FREE(frame);
     180                        return NT_STATUS_OK;
     181                }
     182                TALLOC_FREE(creds);
     183        }
     184
     185        status = cli_rpc_pipe_open_noauth_transport(cli,
     186                                                    transport,
     187                                                    &ndr_table_netlogon,
     188                                                    &netlogon_pipe);
     189        if (!NT_STATUS_IS_OK(status)) {
     190                DEBUG(5,("%s: failed to open noauth netlogon connection to %s - %s\n",
     191                         __FUNCTION__,
     192                         smbXcli_conn_remote_name(cli->conn),
     193                         nt_errstr(status)));
     194                TALLOC_FREE(frame);
     195                return status;
     196        }
     197        talloc_steal(frame, netlogon_pipe);
     198
     199        status = netlogon_creds_cli_auth(netlogon_creds,
     200                                         netlogon_pipe->binding_handle,
     201                                         current_nt_hash,
     202                                         previous_nt_hash);
     203        if (!NT_STATUS_IS_OK(status)) {
     204                TALLOC_FREE(frame);
     205                return status;
     206        }
     207
     208        status = netlogon_creds_cli_get(netlogon_creds,
     209                                        frame, &creds);
     210        if (!NT_STATUS_IS_OK(status)) {
     211                TALLOC_FREE(frame);
     212                return NT_STATUS_INTERNAL_ERROR;
     213        }
     214
     215        DEBUG(5,("%s: using new netlogon_creds cli[%s/%s] to %s\n",
     216                 __FUNCTION__,
     217                 creds->account_name, creds->computer_name,
     218                 smbXcli_conn_remote_name(cli->conn)));
     219
     220        TALLOC_FREE(frame);
     221        return NT_STATUS_OK;
     222}
     223
     224NTSTATUS rpccli_setup_netlogon_creds_with_creds(struct cli_state *cli,
     225                                                enum dcerpc_transport_t transport,
     226                                                struct netlogon_creds_cli_context *netlogon_creds,
     227                                                bool force_reauth,
     228                                                struct cli_credentials *creds)
     229{
     230        struct samr_Password *current_nt_hash = NULL;
     231        struct samr_Password *previous_nt_hash = NULL;
     232        NTSTATUS status;
     233
     234        current_nt_hash = cli_credentials_get_nt_hash(creds, talloc_tos());
     235        if (current_nt_hash == NULL) {
     236                return NT_STATUS_NO_MEMORY;
     237        }
     238
     239        previous_nt_hash = cli_credentials_get_old_nt_hash(creds, talloc_tos());
     240
     241        status = rpccli_setup_netlogon_creds(cli, transport,
     242                                             netlogon_creds,
     243                                             force_reauth,
     244                                             *current_nt_hash,
     245                                             previous_nt_hash);
     246        TALLOC_FREE(current_nt_hash);
     247        TALLOC_FREE(previous_nt_hash);
     248        if (!NT_STATUS_IS_OK(status)) {
     249                return status;
     250        }
     251
     252        return NT_STATUS_OK;
     253}
     254
     255static NTSTATUS map_validation_to_info3(TALLOC_CTX *mem_ctx,
     256                                        uint16_t validation_level,
     257                                        union netr_Validation *validation,
     258                                        struct netr_SamInfo3 **info3_p)
     259{
     260        struct netr_SamInfo3 *info3;
     261        NTSTATUS status;
     262
     263        if (validation == NULL) {
    59264                return NT_STATUS_INVALID_PARAMETER;
    60265        }
    61266
    62         TALLOC_FREE(cli->dc);
    63 
    64         /* Store the machine account password we're going to use. */
    65         memcpy(password.hash, machine_pwd, 16);
    66 
    67         fstr_sprintf( mach_acct, "%s$", machine_account);
    68 
    69  again:
    70         /* Create the client challenge. */
    71         generate_random_buffer(clnt_chal_send.data, 8);
    72 
    73         /* Get the server challenge. */
    74         status = dcerpc_netr_ServerReqChallenge(b, talloc_tos(),
    75                                                 cli->srv_name_slash,
    76                                                 clnt_name,
    77                                                 &clnt_chal_send,
    78                                                 &srv_chal_recv,
    79                                                 &result);
    80         if (!NT_STATUS_IS_OK(status)) {
    81                 return status;
    82         }
    83         if (!NT_STATUS_IS_OK(result)) {
    84                 return result;
    85         }
    86 
    87         /* Calculate the session key and client credentials */
    88 
    89         cli->dc = netlogon_creds_client_init(cli,
    90                                     mach_acct,
    91                                     clnt_name,
    92                                     &clnt_chal_send,
    93                                     &srv_chal_recv,
    94                                     &password,
    95                                     &clnt_chal_send,
    96                                     neg_flags);
    97 
    98         if (!cli->dc) {
    99                 return NT_STATUS_NO_MEMORY;
    100         }
    101 
    102         /*
    103          * Send client auth-2 challenge and receive server repy.
    104          */
    105 
    106         status = dcerpc_netr_ServerAuthenticate2(b, talloc_tos(),
    107                                                  cli->srv_name_slash,
    108                                                  cli->dc->account_name,
    109                                                  sec_chan_type,
    110                                                  cli->dc->computer_name,
    111                                                  &clnt_chal_send, /* input. */
    112                                                  &srv_chal_recv, /* output. */
    113                                                  &neg_flags,
    114                                                  &result);
    115         if (!NT_STATUS_IS_OK(status)) {
    116                 return status;
    117         }
    118         /* we might be talking to NT4, so let's downgrade in that case and retry
    119          * with the returned neg_flags - gd */
    120 
    121         if (NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) && !retried) {
    122                 retried = true;
    123                 TALLOC_FREE(cli->dc);
    124                 goto again;
    125         }
    126 
    127         if (!NT_STATUS_IS_OK(result)) {
    128                 return result;
    129         }
    130 
    131         /*
    132          * Check the returned value using the initial
    133          * server received challenge.
    134          */
    135 
    136         if (!netlogon_creds_client_check(cli->dc, &srv_chal_recv)) {
    137                 /*
    138                  * Server replied with bad credential. Fail.
    139                  */
    140                 DEBUG(0,("rpccli_netlogon_setup_creds: server %s "
    141                         "replied with bad credential\n",
    142                         cli->desthost ));
    143                 return NT_STATUS_ACCESS_DENIED;
    144         }
    145 
    146         DEBUG(5,("rpccli_netlogon_setup_creds: server %s credential "
    147                 "chain established.\n",
    148                 cli->desthost ));
    149 
    150         cli->dc->negotiate_flags = neg_flags;
    151         *neg_flags_inout = neg_flags;
     267        switch (validation_level) {
     268        case 3:
     269                if (validation->sam3 == NULL) {
     270                        return NT_STATUS_INVALID_PARAMETER;
     271                }
     272
     273                info3 = talloc_move(mem_ctx, &validation->sam3);
     274                break;
     275        case 6:
     276                if (validation->sam6 == NULL) {
     277                        return NT_STATUS_INVALID_PARAMETER;
     278                }
     279
     280                info3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
     281                if (info3 == NULL) {
     282                        return NT_STATUS_NO_MEMORY;
     283                }
     284                status = copy_netr_SamBaseInfo(info3, &validation->sam6->base, &info3->base);
     285                if (!NT_STATUS_IS_OK(status)) {
     286                        TALLOC_FREE(info3);
     287                        return status;
     288                }
     289
     290                info3->sidcount = validation->sam6->sidcount;
     291                info3->sids = talloc_move(info3, &validation->sam6->sids);
     292                break;
     293        default:
     294                return NT_STATUS_BAD_VALIDATION_CLASS;
     295        }
     296
     297        *info3_p = info3;
    152298
    153299        return NT_STATUS_OK;
     
    156302/* Logon domain user */
    157303
    158 NTSTATUS rpccli_netlogon_sam_logon(struct rpc_pipe_client *cli,
    159                                    TALLOC_CTX *mem_ctx,
    160                                    uint32 logon_parameters,
    161                                    const char *domain,
    162                                    const char *username,
    163                                    const char *password,
    164                                    const char *workstation,
    165                                    uint16_t validation_level,
    166                                    int logon_type)
    167 {
    168         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
    169         NTSTATUS status;
    170         struct netr_Authenticator clnt_creds;
    171         struct netr_Authenticator ret_creds;
     304NTSTATUS rpccli_netlogon_password_logon(struct netlogon_creds_cli_context *creds,
     305                                        struct dcerpc_binding_handle *binding_handle,
     306                                        TALLOC_CTX *mem_ctx,
     307                                        uint32_t logon_parameters,
     308                                        const char *domain,
     309                                        const char *username,
     310                                        const char *password,
     311                                        const char *workstation,
     312                                        enum netr_LogonInfoClass logon_type,
     313                                        struct netr_SamInfo3 **info3)
     314{
     315        TALLOC_CTX *frame = talloc_stackframe();
     316        NTSTATUS status;
    172317        union netr_LogonLevel *logon;
    173         union netr_Validation validation;
    174         uint8_t authoritative;
    175         fstring clnt_name_slash;
    176         struct dcerpc_binding_handle *b = cli->binding_handle;
    177 
    178         ZERO_STRUCT(ret_creds);
    179 
    180         logon = TALLOC_ZERO_P(mem_ctx, union netr_LogonLevel);
    181         if (!logon) {
    182                 return NT_STATUS_NO_MEMORY;
    183         }
    184 
    185         if (workstation) {
    186                 fstr_sprintf( clnt_name_slash, "\\\\%s", workstation );
    187         } else {
    188                 fstr_sprintf( clnt_name_slash, "\\\\%s", global_myname() );
     318        uint16_t validation_level = 0;
     319        union netr_Validation *validation = NULL;
     320        uint8_t authoritative = 0;
     321        uint32_t flags = 0;
     322        char *workstation_slash = NULL;
     323
     324        logon = talloc_zero(frame, union netr_LogonLevel);
     325        if (logon == NULL) {
     326                TALLOC_FREE(frame);
     327                return NT_STATUS_NO_MEMORY;
     328        }
     329
     330        if (workstation == NULL) {
     331                workstation = lp_netbios_name();
     332        }
     333
     334        workstation_slash = talloc_asprintf(frame, "\\\\%s", workstation);
     335        if (workstation_slash == NULL) {
     336                TALLOC_FREE(frame);
     337                return NT_STATUS_NO_MEMORY;
    189338        }
    190339
    191340        /* Initialise input parameters */
    192 
    193         netlogon_creds_client_authenticator(cli->dc, &clnt_creds);
    194341
    195342        switch (logon_type) {
     
    201348                struct samr_Password ntpassword;
    202349
    203                 password_info = TALLOC_ZERO_P(mem_ctx, struct netr_PasswordInfo);
    204                 if (!password_info) {
     350                password_info = talloc_zero(frame, struct netr_PasswordInfo);
     351                if (password_info == NULL) {
     352                        TALLOC_FREE(frame);
    205353                        return NT_STATUS_NO_MEMORY;
    206354                }
    207355
    208356                nt_lm_owf_gen(password, ntpassword.hash, lmpassword.hash);
    209 
    210                 if (cli->dc->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
    211                         netlogon_creds_arcfour_crypt(cli->dc, lmpassword.hash, 16);
    212                         netlogon_creds_arcfour_crypt(cli->dc, ntpassword.hash, 16);
    213                 } else {
    214                         netlogon_creds_des_encrypt(cli->dc, &lmpassword);
    215                         netlogon_creds_des_encrypt(cli->dc, &ntpassword);
    216                 }
    217357
    218358                password_info->identity_info.domain_name.string         = domain;
     
    221361                password_info->identity_info.logon_id_high              = 0xbeef;
    222362                password_info->identity_info.account_name.string        = username;
    223                 password_info->identity_info.workstation.string         = clnt_name_slash;
     363                password_info->identity_info.workstation.string         = workstation_slash;
    224364
    225365                password_info->lmpassword = lmpassword;
     
    232372        case NetlogonNetworkInformation: {
    233373                struct netr_NetworkInfo *network_info;
    234                 uint8 chal[8];
     374                uint8_t chal[8];
    235375                unsigned char local_lm_response[24];
    236376                unsigned char local_nt_response[24];
     
    241381                ZERO_STRUCT(nt);
    242382
    243                 network_info = TALLOC_ZERO_P(mem_ctx, struct netr_NetworkInfo);
    244                 if (!network_info) {
     383                network_info = talloc_zero(frame, struct netr_NetworkInfo);
     384                if (network_info == NULL) {
     385                        TALLOC_FREE(frame);
    245386                        return NT_STATUS_NO_MEMORY;
    246387                }
     
    262403                network_info->identity_info.logon_id_high               = 0xbeef;
    263404                network_info->identity_info.account_name.string         = username;
    264                 network_info->identity_info.workstation.string          = clnt_name_slash;
     405                network_info->identity_info.workstation.string          = workstation_slash;
    265406
    266407                memcpy(network_info->challenge, chal, 8);
     
    275416                DEBUG(0, ("switch value %d not supported\n",
    276417                        logon_type));
     418                TALLOC_FREE(frame);
    277419                return NT_STATUS_INVALID_INFO_CLASS;
    278420        }
    279421
    280         status = dcerpc_netr_LogonSamLogon(b, mem_ctx,
    281                                            cli->srv_name_slash,
    282                                            global_myname(),
    283                                            &clnt_creds,
    284                                            &ret_creds,
    285                                            logon_type,
    286                                            logon,
    287                                            validation_level,
    288                                            &validation,
    289                                            &authoritative,
    290                                            &result);
    291         if (!NT_STATUS_IS_OK(status)) {
    292                 return status;
    293         }
    294 
    295         /* Always check returned credentials */
    296         if (!netlogon_creds_client_check(cli->dc, &ret_creds.cred)) {
    297                 DEBUG(0,("rpccli_netlogon_sam_logon: credentials chain check failed\n"));
    298                 return NT_STATUS_ACCESS_DENIED;
    299         }
    300 
    301         return result;
    302 }
    303 
    304 static NTSTATUS map_validation_to_info3(TALLOC_CTX *mem_ctx,
    305                                         uint16_t validation_level,
    306                                         union netr_Validation *validation,
    307                                         struct netr_SamInfo3 **info3_p)
    308 {
    309         struct netr_SamInfo3 *info3;
    310         NTSTATUS status;
    311 
    312         if (validation == NULL) {
    313                 return NT_STATUS_INVALID_PARAMETER;
    314         }
    315 
    316         switch (validation_level) {
    317         case 3:
    318                 if (validation->sam3 == NULL) {
    319                         return NT_STATUS_INVALID_PARAMETER;
    320                 }
    321 
    322                 info3 = talloc_move(mem_ctx, &validation->sam3);
    323                 break;
    324         case 6:
    325                 if (validation->sam6 == NULL) {
    326                         return NT_STATUS_INVALID_PARAMETER;
    327                 }
    328 
    329                 info3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
    330                 if (info3 == NULL) {
    331                         return NT_STATUS_NO_MEMORY;
    332                 }
    333                 status = copy_netr_SamBaseInfo(info3, &validation->sam6->base, &info3->base);
    334                 if (!NT_STATUS_IS_OK(status)) {
    335                         TALLOC_FREE(info3);
    336                         return status;
    337                 }
    338 
    339                 info3->sidcount = validation->sam6->sidcount;
    340                 info3->sids = talloc_move(info3, &validation->sam6->sids);
    341                 break;
    342         default:
    343                 return NT_STATUS_BAD_VALIDATION_CLASS;
    344         }
    345 
    346         *info3_p = info3;
     422        status = netlogon_creds_cli_LogonSamLogon(creds,
     423                                                  binding_handle,
     424                                                  logon_type,
     425                                                  logon,
     426                                                  frame,
     427                                                  &validation_level,
     428                                                  &validation,
     429                                                  &authoritative,
     430                                                  &flags);
     431        if (!NT_STATUS_IS_OK(status)) {
     432                TALLOC_FREE(frame);
     433                return status;
     434        }
     435
     436        status = map_validation_to_info3(mem_ctx,
     437                                         validation_level, validation,
     438                                         info3);
     439        TALLOC_FREE(frame);
     440        if (!NT_STATUS_IS_OK(status)) {
     441                return status;
     442        }
     443
    347444
    348445        return NT_STATUS_OK;
     
    355452 **/
    356453
    357 NTSTATUS rpccli_netlogon_sam_network_logon(struct rpc_pipe_client *cli,
    358                                            TALLOC_CTX *mem_ctx,
    359                                            uint32 logon_parameters,
    360                                            const char *server,
    361                                            const char *username,
    362                                            const char *domain,
    363                                            const char *workstation,
    364                                            const uint8 chal[8],
    365                                            uint16_t validation_level,
    366                                            DATA_BLOB lm_response,
    367                                            DATA_BLOB nt_response,
    368                                            struct netr_SamInfo3 **info3)
    369 {
    370         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
     454
     455NTSTATUS rpccli_netlogon_network_logon(struct netlogon_creds_cli_context *creds,
     456                                       struct dcerpc_binding_handle *binding_handle,
     457                                       TALLOC_CTX *mem_ctx,
     458                                       uint32_t logon_parameters,
     459                                       const char *username,
     460                                       const char *domain,
     461                                       const char *workstation,
     462                                       const uint8_t chal[8],
     463                                       DATA_BLOB lm_response,
     464                                       DATA_BLOB nt_response,
     465                                       uint8_t *authoritative,
     466                                       uint32_t *flags,
     467                                       struct netr_SamInfo3 **info3)
     468{
    371469        NTSTATUS status;
    372470        const char *workstation_name_slash;
    373         const char *server_name_slash;
    374         struct netr_Authenticator clnt_creds;
    375         struct netr_Authenticator ret_creds;
    376471        union netr_LogonLevel *logon = NULL;
    377472        struct netr_NetworkInfo *network_info;
    378         uint8_t authoritative;
    379         union netr_Validation validation;
     473        uint16_t validation_level = 0;
     474        union netr_Validation *validation = NULL;
     475        uint8_t _authoritative = 0;
     476        uint32_t _flags = 0;
    380477        struct netr_ChallengeResponse lm;
    381478        struct netr_ChallengeResponse nt;
    382         struct dcerpc_binding_handle *b = cli->binding_handle;
    383479
    384480        *info3 = NULL;
    385481
    386         ZERO_STRUCT(ret_creds);
     482        if (authoritative == NULL) {
     483                authoritative = &_authoritative;
     484        }
     485        if (flags == NULL) {
     486                flags = &_flags;
     487        }
    387488
    388489        ZERO_STRUCT(lm);
    389490        ZERO_STRUCT(nt);
    390491
    391         logon = TALLOC_ZERO_P(mem_ctx, union netr_LogonLevel);
     492        logon = talloc_zero(mem_ctx, union netr_LogonLevel);
    392493        if (!logon) {
    393494                return NT_STATUS_NO_MEMORY;
    394495        }
    395496
    396         network_info = TALLOC_ZERO_P(mem_ctx, struct netr_NetworkInfo);
     497        network_info = talloc_zero(mem_ctx, struct netr_NetworkInfo);
    397498        if (!network_info) {
    398499                return NT_STATUS_NO_MEMORY;
    399         }
    400 
    401         netlogon_creds_client_authenticator(cli->dc, &clnt_creds);
    402 
    403         if (server[0] != '\\' && server[1] != '\\') {
    404                 server_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", server);
    405         } else {
    406                 server_name_slash = server;
    407500        }
    408501
     
    413506        }
    414507
    415         if (!workstation_name_slash || !server_name_slash) {
     508        if (!workstation_name_slash) {
    416509                DEBUG(0, ("talloc_asprintf failed!\n"));
    417510                return NT_STATUS_NO_MEMORY;
     
    440533        /* Marshall data and send request */
    441534
    442         status = dcerpc_netr_LogonSamLogon(b, mem_ctx,
    443                                            server_name_slash,
    444                                            global_myname(),
    445                                            &clnt_creds,
    446                                            &ret_creds,
    447                                            NetlogonNetworkInformation,
    448                                            logon,
    449                                            validation_level,
    450                                            &validation,
    451                                            &authoritative,
    452                                            &result);
    453         if (!NT_STATUS_IS_OK(status)) {
    454                 return status;
    455         }
    456 
    457         /* Always check returned credentials. */
    458         if (!netlogon_creds_client_check(cli->dc, &ret_creds.cred)) {
    459                 DEBUG(0,("rpccli_netlogon_sam_network_logon: credentials chain check failed\n"));
    460                 return NT_STATUS_ACCESS_DENIED;
    461         }
    462 
    463         if (!NT_STATUS_IS_OK(result)) {
    464                 return result;
    465         }
    466 
    467         netlogon_creds_decrypt_samlogon(cli->dc, validation_level, &validation);
    468 
    469         result = map_validation_to_info3(mem_ctx, validation_level, &validation, info3);
    470         if (!NT_STATUS_IS_OK(result)) {
    471                 return result;
    472         }
    473 
    474         return result;
    475 }
    476 
    477 NTSTATUS rpccli_netlogon_sam_network_logon_ex(struct rpc_pipe_client *cli,
    478                                               TALLOC_CTX *mem_ctx,
    479                                               uint32 logon_parameters,
    480                                               const char *server,
    481                                               const char *username,
    482                                               const char *domain,
    483                                               const char *workstation,
    484                                               const uint8 chal[8],
    485                                               uint16_t validation_level,
    486                                               DATA_BLOB lm_response,
    487                                               DATA_BLOB nt_response,
    488                                               struct netr_SamInfo3 **info3)
    489 {
    490         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
    491         NTSTATUS status;
    492         const char *workstation_name_slash;
    493         const char *server_name_slash;
    494         union netr_LogonLevel *logon = NULL;
    495         struct netr_NetworkInfo *network_info;
    496         uint8_t authoritative;
    497         union netr_Validation validation;
    498         struct netr_ChallengeResponse lm;
    499         struct netr_ChallengeResponse nt;
    500         uint32_t flags = 0;
    501         struct dcerpc_binding_handle *b = cli->binding_handle;
    502 
    503         *info3 = NULL;
    504 
    505         ZERO_STRUCT(lm);
    506         ZERO_STRUCT(nt);
    507 
    508         logon = TALLOC_ZERO_P(mem_ctx, union netr_LogonLevel);
    509         if (!logon) {
    510                 return NT_STATUS_NO_MEMORY;
    511         }
    512 
    513         network_info = TALLOC_ZERO_P(mem_ctx, struct netr_NetworkInfo);
    514         if (!network_info) {
    515                 return NT_STATUS_NO_MEMORY;
    516         }
    517 
    518         if (server[0] != '\\' && server[1] != '\\') {
    519                 server_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", server);
    520         } else {
    521                 server_name_slash = server;
    522         }
    523 
    524         if (workstation[0] != '\\' && workstation[1] != '\\') {
    525                 workstation_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", workstation);
    526         } else {
    527                 workstation_name_slash = workstation;
    528         }
    529 
    530         if (!workstation_name_slash || !server_name_slash) {
    531                 DEBUG(0, ("talloc_asprintf failed!\n"));
    532                 return NT_STATUS_NO_MEMORY;
    533         }
    534 
    535         /* Initialise input parameters */
    536 
    537         lm.data = lm_response.data;
    538         lm.length = lm_response.length;
    539         nt.data = nt_response.data;
    540         nt.length = nt_response.length;
    541 
    542         network_info->identity_info.domain_name.string          = domain;
    543         network_info->identity_info.parameter_control           = logon_parameters;
    544         network_info->identity_info.logon_id_low                = 0xdead;
    545         network_info->identity_info.logon_id_high               = 0xbeef;
    546         network_info->identity_info.account_name.string         = username;
    547         network_info->identity_info.workstation.string          = workstation_name_slash;
    548 
    549         memcpy(network_info->challenge, chal, 8);
    550         network_info->nt = nt;
    551         network_info->lm = lm;
    552 
    553         logon->network = network_info;
    554 
    555         /* Marshall data and send request */
    556 
    557         status = dcerpc_netr_LogonSamLogonEx(b, mem_ctx,
    558                                              server_name_slash,
    559                                              global_myname(),
    560                                              NetlogonNetworkInformation,
    561                                              logon,
    562                                              validation_level,
    563                                              &validation,
    564                                              &authoritative,
    565                                              &flags,
    566                                              &result);
    567         if (!NT_STATUS_IS_OK(status)) {
    568                 return status;
    569         }
    570 
    571         if (!NT_STATUS_IS_OK(result)) {
    572                 return result;
    573         }
    574 
    575         netlogon_creds_decrypt_samlogon(cli->dc, validation_level, &validation);
    576 
    577         result = map_validation_to_info3(mem_ctx, validation_level, &validation, info3);
    578         if (!NT_STATUS_IS_OK(result)) {
    579                 return result;
    580         }
    581 
    582         return result;
    583 }
    584 
    585 /*********************************************************
    586  Change the domain password on the PDC.
    587 
    588  Just changes the password betwen the two values specified.
    589 
    590  Caller must have the cli connected to the netlogon pipe
    591  already.
    592 **********************************************************/
    593 
    594 NTSTATUS rpccli_netlogon_set_trust_password(struct rpc_pipe_client *cli,
    595                                             TALLOC_CTX *mem_ctx,
    596                                             const char *account_name,
    597                                             const unsigned char orig_trust_passwd_hash[16],
    598                                             const char *new_trust_pwd_cleartext,
    599                                             const unsigned char new_trust_passwd_hash[16],
    600                                             enum netr_SchannelType sec_channel_type)
    601 {
    602         NTSTATUS result, status;
    603         struct netr_Authenticator clnt_creds, srv_cred;
    604         struct dcerpc_binding_handle *b = cli->binding_handle;
    605 
    606         if (!cli->dc) {
    607                 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
    608                 result = rpccli_netlogon_setup_creds(cli,
    609                                                      cli->desthost, /* server name */
    610                                                      lp_workgroup(), /* domain */
    611                                                      global_myname(), /* client name */
    612                                                      account_name, /* machine account name */
    613                                                      orig_trust_passwd_hash,
    614                                                      sec_channel_type,
    615                                                      &neg_flags);
    616                 if (!NT_STATUS_IS_OK(result)) {
    617                         DEBUG(3,("rpccli_netlogon_set_trust_password: unable to setup creds (%s)!\n",
    618                                  nt_errstr(result)));
    619                         return result;
    620                 }
    621         }
    622 
    623         netlogon_creds_client_authenticator(cli->dc, &clnt_creds);
    624 
    625         if (cli->dc->negotiate_flags & NETLOGON_NEG_PASSWORD_SET2) {
    626 
    627                 struct netr_CryptPassword new_password;
    628                 uint32_t old_timeout;
    629 
    630                 init_netr_CryptPassword(new_trust_pwd_cleartext,
    631                                         cli->dc->session_key,
    632                                         &new_password);
    633 
    634                 old_timeout = dcerpc_binding_handle_set_timeout(b, 600000);
    635 
    636                 status = dcerpc_netr_ServerPasswordSet2(b, mem_ctx,
    637                                                         cli->srv_name_slash,
    638                                                         cli->dc->account_name,
    639                                                         sec_channel_type,
    640                                                         cli->dc->computer_name,
    641                                                         &clnt_creds,
    642                                                         &srv_cred,
    643                                                         &new_password,
    644                                                         &result);
    645 
    646                 dcerpc_binding_handle_set_timeout(b, old_timeout);
    647 
    648                 if (!NT_STATUS_IS_OK(status)) {
    649                         DEBUG(0,("dcerpc_netr_ServerPasswordSet2 failed: %s\n",
    650                                 nt_errstr(status)));
    651                         return status;
    652                 }
    653         } else {
    654 
    655                 struct samr_Password new_password;
    656                 uint32_t old_timeout;
    657 
    658                 memcpy(new_password.hash, new_trust_passwd_hash, sizeof(new_password.hash));
    659                 netlogon_creds_des_encrypt(cli->dc, &new_password);
    660 
    661                 old_timeout = dcerpc_binding_handle_set_timeout(b, 600000);
    662 
    663                 status = dcerpc_netr_ServerPasswordSet(b, mem_ctx,
    664                                                        cli->srv_name_slash,
    665                                                        cli->dc->account_name,
    666                                                        sec_channel_type,
    667                                                        cli->dc->computer_name,
    668                                                        &clnt_creds,
    669                                                        &srv_cred,
    670                                                        &new_password,
    671                                                        &result);
    672 
    673                 dcerpc_binding_handle_set_timeout(b, old_timeout);
    674 
    675                 if (!NT_STATUS_IS_OK(status)) {
    676                         DEBUG(0,("dcerpc_netr_ServerPasswordSet failed: %s\n",
    677                                 nt_errstr(status)));
    678                         return status;
    679                 }
    680         }
    681 
    682         /* Always check returned credentials. */
    683         if (!netlogon_creds_client_check(cli->dc, &srv_cred.cred)) {
    684                 DEBUG(0,("credentials chain check failed\n"));
    685                 return NT_STATUS_ACCESS_DENIED;
    686         }
    687 
    688         if (!NT_STATUS_IS_OK(result)) {
    689                 DEBUG(0,("dcerpc_netr_ServerPasswordSet{2} failed: %s\n",
    690                         nt_errstr(result)));
    691                 return result;
    692         }
    693 
    694         return result;
    695 }
    696 
     535        status = netlogon_creds_cli_LogonSamLogon(creds,
     536                                                  binding_handle,
     537                                                  NetlogonNetworkInformation,
     538                                                  logon,
     539                                                  mem_ctx,
     540                                                  &validation_level,
     541                                                  &validation,
     542                                                  authoritative,
     543                                                  flags);
     544        if (!NT_STATUS_IS_OK(status)) {
     545                return status;
     546        }
     547
     548        status = map_validation_to_info3(mem_ctx,
     549                                         validation_level, validation,
     550                                         info3);
     551        if (!NT_STATUS_IS_OK(status)) {
     552                return status;
     553        }
     554
     555        return NT_STATUS_OK;
     556}
  • vendor/current/source3/rpc_client/cli_netlogon.h

    r740 r988  
    2424#define _RPC_CLIENT_CLI_NETLOGON_H_
    2525
     26struct cli_state;
     27struct messaging_context;
     28struct cli_credentials;
     29struct netlogon_creds_cli_context;
     30struct dcerpc_binding_handle;
     31#include "librpc/rpc/rpc_common.h"
     32
    2633/* The following definitions come from rpc_client/cli_netlogon.c  */
    2734
    28 NTSTATUS rpccli_netlogon_setup_creds(struct rpc_pipe_client *cli,
    29                                      const char *server_name,
    30                                      const char *domain,
    31                                      const char *clnt_name,
    32                                      const char *machine_account,
    33                                      const unsigned char machine_pwd[16],
    34                                      enum netr_SchannelType sec_chan_type,
    35                                      uint32_t *neg_flags_inout);
    36 NTSTATUS rpccli_netlogon_sam_logon(struct rpc_pipe_client *cli,
    37                                    TALLOC_CTX *mem_ctx,
    38                                    uint32 logon_parameters,
    39                                    const char *domain,
    40                                    const char *username,
    41                                    const char *password,
    42                                    const char *workstation,
    43                                    uint16_t validation_level,
    44                                    int logon_type);
    45 NTSTATUS rpccli_netlogon_sam_network_logon(struct rpc_pipe_client *cli,
    46                                            TALLOC_CTX *mem_ctx,
    47                                            uint32 logon_parameters,
    48                                            const char *server,
    49                                            const char *username,
    50                                            const char *domain,
    51                                            const char *workstation,
    52                                            const uint8 chal[8],
    53                                            uint16_t validation_level,
    54                                            DATA_BLOB lm_response,
    55                                            DATA_BLOB nt_response,
    56                                            struct netr_SamInfo3 **info3);
    57 NTSTATUS rpccli_netlogon_sam_network_logon_ex(struct rpc_pipe_client *cli,
    58                                               TALLOC_CTX *mem_ctx,
    59                                               uint32 logon_parameters,
    60                                               const char *server,
    61                                               const char *username,
    62                                               const char *domain,
    63                                               const char *workstation,
    64                                               const uint8 chal[8],
    65                                               uint16_t validation_level,
    66                                               DATA_BLOB lm_response,
    67                                               DATA_BLOB nt_response,
    68                                               struct netr_SamInfo3 **info3);
    69 NTSTATUS rpccli_netlogon_set_trust_password(struct rpc_pipe_client *cli,
    70                                             TALLOC_CTX *mem_ctx,
    71                                             const char *account_name,
    72                                             const unsigned char orig_trust_passwd_hash[16],
    73                                             const char *new_trust_pwd_cleartext,
    74                                             const unsigned char new_trust_passwd_hash[16],
    75                                             enum netr_SchannelType sec_channel_type);
     35NTSTATUS rpccli_pre_open_netlogon_creds(void);
     36NTSTATUS rpccli_create_netlogon_creds(const char *server_computer,
     37                                      const char *server_netbios_domain,
     38                                      const char *client_account,
     39                                      enum netr_SchannelType sec_chan_type,
     40                                      struct messaging_context *msg_ctx,
     41                                      TALLOC_CTX *mem_ctx,
     42                                      struct netlogon_creds_cli_context **netlogon_creds);
     43NTSTATUS rpccli_create_netlogon_creds_with_creds(struct cli_credentials *creds,
     44                                                 const char *server_computer,
     45                                                 struct messaging_context *msg_ctx,
     46                                                 TALLOC_CTX *mem_ctx,
     47                                                 struct netlogon_creds_cli_context **netlogon_creds);
     48NTSTATUS rpccli_setup_netlogon_creds(struct cli_state *cli,
     49                                     enum dcerpc_transport_t transport,
     50                                     struct netlogon_creds_cli_context *netlogon_creds,
     51                                     bool force_reauth,
     52                                     struct samr_Password current_nt_hash,
     53                                     const struct samr_Password *previous_nt_hash);
     54NTSTATUS rpccli_setup_netlogon_creds_with_creds(struct cli_state *cli,
     55                                                enum dcerpc_transport_t transport,
     56                                                struct netlogon_creds_cli_context *netlogon_creds,
     57                                                bool force_reauth,
     58                                                struct cli_credentials *creds);
     59NTSTATUS rpccli_netlogon_password_logon(struct netlogon_creds_cli_context *creds,
     60                                        struct dcerpc_binding_handle *binding_handle,
     61                                        TALLOC_CTX *mem_ctx,
     62                                        uint32_t logon_parameters,
     63                                        const char *domain,
     64                                        const char *username,
     65                                        const char *password,
     66                                        const char *workstation,
     67                                        enum netr_LogonInfoClass logon_type,
     68                                        struct netr_SamInfo3 **info3);
     69NTSTATUS rpccli_netlogon_network_logon(struct netlogon_creds_cli_context *creds,
     70                                       struct dcerpc_binding_handle *binding_handle,
     71                                       TALLOC_CTX *mem_ctx,
     72                                       uint32_t logon_parameters,
     73                                       const char *username,
     74                                       const char *domain,
     75                                       const char *workstation,
     76                                       const uint8_t chal[8],
     77                                       DATA_BLOB lm_response,
     78                                       DATA_BLOB nt_response,
     79                                       uint8_t *authoritative,
     80                                       uint32_t *flags,
     81                                       struct netr_SamInfo3 **info3);
    7682
    7783#endif /* _RPC_CLIENT_CLI_NETLOGON_H_ */
  • vendor/current/source3/rpc_client/cli_pipe.c

    r919 r988  
    44 *  Largely rewritten by Jeremy Allison             2005.
    55 *  Heavily modified by Simo Sorce                  2010.
     6 *  Copyright Andrew Bartlett                       2011.
    67 *
    78 *  This program is free software; you can redistribute it and/or modify
     
    2223#include "../lib/util/tevent_ntstatus.h"
    2324#include "librpc/gen_ndr/ndr_epmapper_c.h"
    24 #include "../librpc/gen_ndr/ndr_schannel.h"
    2525#include "../librpc/gen_ndr/ndr_dssetup.h"
    2626#include "../libcli/auth/schannel.h"
    27 #include "../libcli/auth/spnego.h"
    28 #include "../libcli/auth/ntlmssp.h"
    29 #include "ntlmssp_wrap.h"
     27#include "../libcli/auth/netlogon_creds_cli.h"
     28#include "auth_generic.h"
    3029#include "librpc/gen_ndr/ndr_dcerpc.h"
    3130#include "librpc/gen_ndr/ndr_netlogon_c.h"
    3231#include "librpc/rpc/dcerpc.h"
    33 #include "librpc/crypto/gse.h"
    34 #include "librpc/crypto/spnego.h"
    3532#include "rpc_dce.h"
    3633#include "cli_pipe.h"
    37 #include "client.h"
     34#include "libsmb/libsmb.h"
     35#include "auth/gensec/gensec.h"
     36#include "auth/credentials/credentials.h"
     37#include "../libcli/smb/smbXcli_base.h"
    3838
    3939#undef DBGC_CLASS
     
    5757 ********************************************************************/
    5858
    59 static uint32 get_rpc_call_id(void)
    60 {
    61         static uint32 call_id = 0;
     59static uint32_t get_rpc_call_id(void)
     60{
     61        static uint32_t call_id = 0;
    6262        return ++call_id;
    6363}
     
    6969
    7070struct rpc_read_state {
    71         struct event_context *ev;
     71        struct tevent_context *ev;
    7272        struct rpc_cli_transport *transport;
    7373        uint8_t *data;
     
    7979
    8080static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
    81                                         struct event_context *ev,
     81                                        struct tevent_context *ev,
    8282                                        struct rpc_cli_transport *transport,
    8383                                        uint8_t *data, size_t size)
     
    149149
    150150struct rpc_write_state {
    151         struct event_context *ev;
     151        struct tevent_context *ev;
    152152        struct rpc_cli_transport *transport;
    153153        const uint8_t *data;
     
    159159
    160160static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
    161                                          struct event_context *ev,
     161                                         struct tevent_context *ev,
    162162                                         struct rpc_cli_transport *transport,
    163163                                         const uint8_t *data, size_t size)
     
    234234
    235235struct get_complete_frag_state {
    236         struct event_context *ev;
     236        struct tevent_context *ev;
    237237        struct rpc_pipe_client *cli;
    238238        uint16_t frag_len;
    239         uint32_t call_id;
    240239        DATA_BLOB *pdu;
    241240};
     
    245244
    246245static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
    247                                                  struct event_context *ev,
     246                                                 struct tevent_context *ev,
    248247                                                 struct rpc_pipe_client *cli,
    249                                                  uint32_t call_id,
    250248                                                 DATA_BLOB *pdu)
    251249{
     
    263261        state->cli = cli;
    264262        state->frag_len = RPC_HEADER_LEN;
    265         state->call_id = call_id;
    266263        state->pdu = pdu;
    267264
     
    291288        }
    292289
    293         if (state->call_id != dcerpc_get_call_id(pdu)) {
    294                 tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
    295                 return tevent_req_post(req, ev);
    296         }
    297 
    298290        /*
    299291         * Ensure we have frag_len bytes of data.
     
    344336        state->frag_len = dcerpc_get_frag_length(state->pdu);
    345337        if (state->frag_len < RPC_HEADER_LEN) {
    346                 tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
    347                 return;
    348         }
    349 
    350         if (state->call_id != dcerpc_get_call_id(state->pdu)) {
    351338                tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
    352339                return;
     
    608595
    609596struct cli_api_pipe_state {
    610         struct event_context *ev;
     597        struct tevent_context *ev;
    611598        struct rpc_cli_transport *transport;
    612599        uint8_t *rdata;
     
    619606
    620607static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
    621                                             struct event_context *ev,
     608                                            struct tevent_context *ev,
    622609                                            struct rpc_cli_transport *transport,
    623610                                            uint8_t *data, size_t data_len,
     
    708695        }
    709696
    710         state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
     697        state->rdata = talloc_array(state, uint8_t, RPC_HEADER_LEN);
    711698        if (tevent_req_nomem(state->rdata, req)) {
    712699                return;
     
    789776
    790777struct rpc_api_pipe_state {
    791         struct event_context *ev;
     778        struct tevent_context *ev;
    792779        struct rpc_pipe_client *cli;
    793780        uint8_t expected_pkt_type;
     
    808795
    809796static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
    810                                             struct event_context *ev,
     797                                            struct tevent_context *ev,
    811798                                            struct rpc_pipe_client *cli,
    812799                                            DATA_BLOB *data, /* Outgoing PDU */
     
    827814        state->expected_pkt_type = expected_pkt_type;
    828815        state->call_id = call_id;
    829         state->incoming_frag = data_blob_null;
    830         state->reply_pdu = data_blob_null;
    831         state->reply_pdu_offset = 0;
    832816        state->endianess = DCERPC_DREP_LE;
    833817
     
    926910        /* Ensure we have enough data for a pdu. */
    927911        subreq = get_complete_frag_send(state, state->ev, state->cli,
    928                                         state->call_id,
    929912                                        &state->incoming_frag);
    930913        if (tevent_req_nomem(subreq, req)) {
     
    10961079
    10971080        subreq = get_complete_frag_send(state, state->ev, state->cli,
    1098                                         state->call_id,
    10991081                                        &state->incoming_frag);
    11001082        if (subreq == NULL) {
     
    11411123
    11421124/*******************************************************************
    1143  Creates spnego auth bind.
    1144  ********************************************************************/
    1145 
    1146 static NTSTATUS create_spnego_auth_bind_req(TALLOC_CTX *mem_ctx,
    1147                                             struct pipe_auth_data *auth,
    1148                                             DATA_BLOB *auth_token)
    1149 {
    1150         struct spnego_context *spnego_ctx;
    1151         DATA_BLOB in_token = data_blob_null;
    1152         NTSTATUS status;
    1153 
    1154         spnego_ctx = talloc_get_type_abort(auth->auth_ctx,
    1155                                            struct spnego_context);
    1156 
    1157         /* Negotiate the initial auth token */
    1158         status = spnego_get_client_auth_token(mem_ctx, spnego_ctx,
    1159                                               &in_token, auth_token);
    1160         if (!NT_STATUS_IS_OK(status)) {
    1161                 return status;
    1162         }
    1163 
    1164         DEBUG(5, ("Created GSS Authentication Token:\n"));
    1165         dump_data(5, auth_token->data, auth_token->length);
    1166 
    1167         return NT_STATUS_OK;
    1168 }
    1169 
    1170 /*******************************************************************
    1171  Creates krb5 auth bind.
    1172  ********************************************************************/
    1173 
    1174 static NTSTATUS create_gssapi_auth_bind_req(TALLOC_CTX *mem_ctx,
    1175                                             struct pipe_auth_data *auth,
    1176                                             DATA_BLOB *auth_token)
    1177 {
    1178         struct gse_context *gse_ctx;
    1179         DATA_BLOB in_token = data_blob_null;
    1180         NTSTATUS status;
    1181 
    1182         gse_ctx = talloc_get_type_abort(auth->auth_ctx,
    1183                                         struct gse_context);
    1184 
    1185         /* Negotiate the initial auth token */
    1186         status = gse_get_client_auth_token(mem_ctx, gse_ctx,
    1187                                            &in_token,
    1188                                            auth_token);
    1189         if (!NT_STATUS_IS_OK(status)) {
    1190                 return status;
    1191         }
    1192 
    1193         DEBUG(5, ("Created GSS Authentication Token:\n"));
    1194         dump_data(5, auth_token->data, auth_token->length);
    1195 
    1196         return NT_STATUS_OK;
    1197 }
    1198 
    1199 /*******************************************************************
    12001125 Creates NTLMSSP auth bind.
    12011126 ********************************************************************/
    12021127
    1203 static NTSTATUS create_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
    1204                                                  DATA_BLOB *auth_token)
    1205 {
    1206         struct auth_ntlmssp_state *ntlmssp_ctx;
     1128static NTSTATUS create_generic_auth_rpc_bind_req(struct rpc_pipe_client *cli,
     1129                                                 TALLOC_CTX *mem_ctx,
     1130                                                 DATA_BLOB *auth_token,
     1131                                                 bool *client_hdr_signing)
     1132{
     1133        struct gensec_security *gensec_security;
    12071134        DATA_BLOB null_blob = data_blob_null;
    12081135        NTSTATUS status;
    12091136
    1210         ntlmssp_ctx = talloc_get_type_abort(cli->auth->auth_ctx,
    1211                                             struct auth_ntlmssp_state);
    1212 
    1213         DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
    1214         status = auth_ntlmssp_update(ntlmssp_ctx, null_blob, auth_token);
    1215 
    1216         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
    1217                 data_blob_free(auth_token);
     1137        gensec_security = cli->auth->auth_ctx;
     1138
     1139        DEBUG(5, ("create_generic_auth_rpc_bind_req: generate first token\n"));
     1140        status = gensec_update(gensec_security, mem_ctx, null_blob, auth_token);
     1141
     1142        if (!NT_STATUS_IS_OK(status) &&
     1143            !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
     1144        {
    12181145                return status;
    12191146        }
    12201147
    1221         DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
    1222         dump_data(5, auth_token->data, auth_token->length);
    1223 
    1224         return NT_STATUS_OK;
    1225 }
    1226 
    1227 /*******************************************************************
    1228  Creates schannel auth bind.
    1229  ********************************************************************/
    1230 
    1231 static NTSTATUS create_schannel_auth_rpc_bind_req(struct rpc_pipe_client *cli,
    1232                                                   DATA_BLOB *auth_token)
    1233 {
    1234         NTSTATUS status;
    1235         struct NL_AUTH_MESSAGE r;
    1236 
    1237         /* Use lp_workgroup() if domain not specified */
    1238 
    1239         if (!cli->auth->domain || !cli->auth->domain[0]) {
    1240                 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
    1241                 if (cli->auth->domain == NULL) {
    1242                         return NT_STATUS_NO_MEMORY;
    1243                 }
    1244         }
    1245 
    1246         /*
    1247          * Now marshall the data into the auth parse_struct.
    1248          */
    1249 
    1250         r.MessageType                   = NL_NEGOTIATE_REQUEST;
    1251         r.Flags                         = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
    1252                                           NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
    1253         r.oem_netbios_domain.a          = cli->auth->domain;
    1254         r.oem_netbios_computer.a        = global_myname();
    1255 
    1256         status = dcerpc_push_schannel_bind(cli, &r, auth_token);
    1257         if (!NT_STATUS_IS_OK(status)) {
     1148        if (client_hdr_signing == NULL) {
    12581149                return status;
    12591150        }
    12601151
    1261         return NT_STATUS_OK;
     1152        if (cli->auth->auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) {
     1153                *client_hdr_signing = false;
     1154                return status;
     1155        }
     1156
     1157        *client_hdr_signing = gensec_have_feature(gensec_security,
     1158                                                GENSEC_FEATURE_SIGN_PKT_HEADER);
     1159
     1160        return status;
    12621161}
    12631162
     
    12681167static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx,
    12691168                                                enum dcerpc_pkt_type ptype,
    1270                                                 uint32 rpc_call_id,
     1169                                                uint32_t rpc_call_id,
    12711170                                                const struct ndr_syntax_id *abstract,
    12721171                                                const struct ndr_syntax_id *transfer,
    12731172                                                const DATA_BLOB *auth_info,
     1173                                                bool client_hdr_signing,
    12741174                                                DATA_BLOB *blob)
    12751175{
    1276         uint16 auth_len = auth_info->length;
     1176        uint16_t auth_len = auth_info->length;
    12771177        NTSTATUS status;
    12781178        union dcerpc_payload u;
    12791179        struct dcerpc_ctx_list ctx_list;
     1180        uint8_t pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
    12801181
    12811182        if (auth_len) {
    12821183                auth_len -= DCERPC_AUTH_TRAILER_LENGTH;
     1184        }
     1185
     1186        if (client_hdr_signing) {
     1187                pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN;
    12831188        }
    12841189
     
    12961201
    12971202        status = dcerpc_push_ncacn_packet(mem_ctx,
    1298                                           ptype,
    1299                                           DCERPC_PFC_FLAG_FIRST |
    1300                                           DCERPC_PFC_FLAG_LAST,
     1203                                          ptype, pfc_flags,
    13011204                                          auth_len,
    13021205                                          rpc_call_id,
     
    13181221                                    struct rpc_pipe_client *cli,
    13191222                                    struct pipe_auth_data *auth,
    1320                                     uint32 rpc_call_id,
     1223                                    uint32_t rpc_call_id,
    13211224                                    const struct ndr_syntax_id *abstract,
    13221225                                    const struct ndr_syntax_id *transfer,
     
    13281231
    13291232        switch (auth->auth_type) {
    1330         case DCERPC_AUTH_TYPE_SCHANNEL:
    1331                 ret = create_schannel_auth_rpc_bind_req(cli, &auth_token);
    1332                 if (!NT_STATUS_IS_OK(ret)) {
    1333                         return ret;
    1334                 }
    1335                 break;
    1336 
    1337         case DCERPC_AUTH_TYPE_NTLMSSP:
    1338                 ret = create_ntlmssp_auth_rpc_bind_req(cli, &auth_token);
    1339                 if (!NT_STATUS_IS_OK(ret)) {
    1340                         return ret;
    1341                 }
    1342                 break;
    1343 
    1344         case DCERPC_AUTH_TYPE_SPNEGO:
    1345                 ret = create_spnego_auth_bind_req(cli, auth, &auth_token);
    1346                 if (!NT_STATUS_IS_OK(ret)) {
    1347                         return ret;
    1348                 }
    1349                 break;
    1350 
    1351         case DCERPC_AUTH_TYPE_KRB5:
    1352                 ret = create_gssapi_auth_bind_req(mem_ctx, auth, &auth_token);
    1353                 if (!NT_STATUS_IS_OK(ret)) {
    1354                         return ret;
    1355                 }
    1356                 break;
    1357 
    1358         case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
    1359                 auth_token = data_blob_talloc(mem_ctx,
    1360                                               "NCALRPC_AUTH_TOKEN",
    1361                                               18);
    1362                 break;
    1363 
    13641233        case DCERPC_AUTH_TYPE_NONE:
    13651234                break;
    13661235
    13671236        default:
    1368                 /* "Can't" happen. */
    1369                 return NT_STATUS_INVALID_INFO_CLASS;
     1237                ret = create_generic_auth_rpc_bind_req(cli, mem_ctx,
     1238                                                       &auth_token,
     1239                                                       &auth->client_hdr_signing);
     1240
     1241                if (!NT_STATUS_IS_OK(ret) &&
     1242                    !NT_STATUS_EQUAL(ret, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
     1243                        return ret;
     1244                }
     1245                break;
    13701246        }
    13711247
     
    13901266                                              transfer,
    13911267                                              &auth_info,
     1268                                              auth->client_hdr_signing,
    13921269                                              rpc_out);
    13931270        return ret;
     
    14021279
    14031280struct rpc_api_pipe_req_state {
    1404         struct event_context *ev;
     1281        struct tevent_context *ev;
    14051282        struct rpc_pipe_client *cli;
    14061283        uint8_t op_num;
    14071284        uint32_t call_id;
    1408         DATA_BLOB *req_data;
     1285        const DATA_BLOB *req_data;
    14091286        uint32_t req_data_sent;
    14101287        DATA_BLOB req_trailer;
     
    14221299                                  bool *is_last_frag);
    14231300
    1424 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
    1425                                          struct event_context *ev,
     1301static struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
     1302                                         struct tevent_context *ev,
    14261303                                         struct rpc_pipe_client *cli,
    14271304                                         uint8_t op_num,
    1428                                          DATA_BLOB *req_data)
     1305                                         const DATA_BLOB *req_data)
    14291306{
    14301307        struct tevent_req *req, *subreq;
     
    15271404
    15281405                c->command = DCERPC_SEC_VT_COMMAND_BITMASK1;
     1406                if (a->client_hdr_signing) {
     1407                        c->u.bitmask1 = DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING;
     1408                }
    15291409                state->verify_bitmask1 = true;
    15301410        }
     
    15471427        }
    15481428
    1549         if (true) { /* We do not support header signing */
     1429        if (!a->hdr_signing) {
    15501430                t->commands = talloc_realloc(t, t->commands,
    15511431                                             struct dcerpc_sec_vt,
     
    16461526                                    DCERPC_REQUEST_LENGTH, total_left,
    16471527                                    state->cli->max_xmit_frag,
    1648                                     CLIENT_NDR_PADDING_SIZE,
    16491528                                    &total_thistime,
    16501529                                    &frag_len, &auth_len, &pad_len);
     
    18091688}
    18101689
    1811 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
     1690static NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
    18121691                               DATA_BLOB *reply_pdu)
    18131692{
     
    18611740        if (r->num_results != 0x1 || ctx.result != 0) {
    18621741                DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
    1863                           r->num_results, ctx.reason));
     1742                          r->num_results, ctx.reason.value));
    18641743        }
    18651744
     
    19481827                                                 transfer,
    19491828                                                 &auth_info,
     1829                                                 false, /* client_hdr_signing */
    19501830                                                 rpc_out);
    19511831        data_blob_free(&auth_info);
     
    19581838
    19591839struct rpc_pipe_bind_state {
    1960         struct event_context *ev;
     1840        struct tevent_context *ev;
    19611841        struct rpc_pipe_client *cli;
    19621842        DATA_BLOB rpc_out;
    19631843        bool auth3;
    19641844        uint32_t rpc_call_id;
    1965         struct netr_Authenticator auth;
    1966         struct netr_Authenticator return_auth;
    1967         struct netlogon_creds_CredentialState *creds;
    1968         union netr_Capabilities capabilities;
    1969         struct netr_LogonGetCapabilities r;
    19701845};
    19711846
    19721847static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
    1973 static void rpc_pipe_bind_step_two_trigger(struct tevent_req *req);
    19741848static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
    19751849                                   struct rpc_pipe_bind_state *state,
     
    19801854
    19811855struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
    1982                                       struct event_context *ev,
     1856                                      struct tevent_context *ev,
    19831857                                      struct rpc_pipe_client *cli,
    19841858                                      struct pipe_auth_data *auth)
     
    20121886                                     &state->rpc_out);
    20131887
    2014         if (!NT_STATUS_IS_OK(status)) {
     1888        if (!NT_STATUS_IS_OK(status) &&
     1889            !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
    20151890                goto post_status;
    20161891        }
     
    20391914                req, struct rpc_pipe_bind_state);
    20401915        struct pipe_auth_data *pauth = state->cli->auth;
    2041         struct auth_ntlmssp_state *ntlmssp_ctx;
    2042         struct spnego_context *spnego_ctx;
    2043         struct gse_context *gse_ctx;
     1916        struct gensec_security *gensec_security;
    20441917        struct ncacn_packet *pkt = NULL;
    20451918        struct dcerpc_auth auth;
     
    20741947
    20751948        case DCERPC_AUTH_TYPE_NONE:
    2076         case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
    20771949                /* Bind complete. */
    20781950                tevent_req_done(req);
    2079                 return;
    2080 
    2081         case DCERPC_AUTH_TYPE_SCHANNEL:
    2082                 rpc_pipe_bind_step_two_trigger(req);
    20831951                return;
    20841952
     
    20881956                        return;
    20891957                }
     1958
    20901959                /* get auth credentials */
    20911960                status = dcerpc_pull_auth_trailer(pkt, talloc_tos(),
     
    21312000
    21322001        case DCERPC_AUTH_TYPE_NONE:
    2133         case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
    2134         case DCERPC_AUTH_TYPE_SCHANNEL:
    21352002                /* Bind complete. */
    21362003                tevent_req_done(req);
    21372004                return;
    21382005
    2139         case DCERPC_AUTH_TYPE_NTLMSSP:
    2140                 ntlmssp_ctx = talloc_get_type_abort(pauth->auth_ctx,
    2141                                                     struct auth_ntlmssp_state);
    2142                 status = auth_ntlmssp_update(ntlmssp_ctx,
    2143                                              auth.credentials, &auth_token);
     2006        default:
     2007                gensec_security = pauth->auth_ctx;
     2008
     2009                if (pkt->pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) {
     2010                        if (pauth->client_hdr_signing) {
     2011                                pauth->hdr_signing = true;
     2012                                gensec_want_feature(gensec_security,
     2013                                                    GENSEC_FEATURE_SIGN_PKT_HEADER);
     2014                        }
     2015                }
     2016
     2017                status = gensec_update(gensec_security, state,
     2018                                       auth.credentials, &auth_token);
    21442019                if (NT_STATUS_EQUAL(status,
    21452020                                    NT_STATUS_MORE_PROCESSING_REQUIRED)) {
     
    21472022                                                        &auth_token);
    21482023                } else if (NT_STATUS_IS_OK(status)) {
     2024                        if (auth_token.length == 0) {
     2025                                /* Bind complete. */
     2026                                tevent_req_done(req);
     2027                                return;
     2028                        }
    21492029                        status = rpc_bind_finish_send(req, state,
    21502030                                                        &auth_token);
    21512031                }
    21522032                break;
    2153 
    2154         case DCERPC_AUTH_TYPE_SPNEGO:
    2155                 spnego_ctx = talloc_get_type_abort(pauth->auth_ctx,
    2156                                                    struct spnego_context);
    2157                 status = spnego_get_client_auth_token(state,
    2158                                                 spnego_ctx,
    2159                                                 &auth.credentials,
    2160                                                 &auth_token);
    2161                 if (!NT_STATUS_IS_OK(status)) {
    2162                         break;
    2163                 }
    2164                 if (auth_token.length == 0) {
    2165                         /* Bind complete. */
    2166                         tevent_req_done(req);
    2167                         return;
    2168                 }
    2169                 if (spnego_require_more_processing(spnego_ctx)) {
    2170                         status = rpc_bind_next_send(req, state,
    2171                                                         &auth_token);
    2172                 } else {
    2173                         status = rpc_bind_finish_send(req, state,
    2174                                                         &auth_token);
    2175                 }
    2176                 break;
    2177 
    2178         case DCERPC_AUTH_TYPE_KRB5:
    2179                 gse_ctx = talloc_get_type_abort(pauth->auth_ctx,
    2180                                                 struct gse_context);
    2181                 status = gse_get_client_auth_token(state,
    2182                                                    gse_ctx,
    2183                                                    &auth.credentials,
    2184                                                    &auth_token);
    2185                 if (!NT_STATUS_IS_OK(status)) {
    2186                         break;
    2187                 }
    2188 
    2189                 if (gse_require_more_processing(gse_ctx)) {
    2190                         status = rpc_bind_next_send(req, state, &auth_token);
    2191                 } else {
    2192                         status = rpc_bind_finish_send(req, state, &auth_token);
    2193                 }
    2194                 break;
    2195 
    2196         default:
    2197                 goto err_out;
    21982033        }
    21992034
     
    22012036                tevent_req_nterror(req, status);
    22022037        }
    2203         return;
    2204 
    2205 err_out:
    2206         DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
    2207                  (unsigned int)state->cli->auth->auth_type));
    2208         tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
    2209 }
    2210 
    2211 static void rpc_pipe_bind_step_two_done(struct tevent_req *subreq);
    2212 
    2213 static void rpc_pipe_bind_step_two_trigger(struct tevent_req *req)
    2214 {
    2215         struct rpc_pipe_bind_state *state =
    2216                 tevent_req_data(req,
    2217                                 struct rpc_pipe_bind_state);
    2218         struct dcerpc_binding_handle *b = state->cli->binding_handle;
    2219         struct schannel_state *schannel_auth =
    2220                 talloc_get_type_abort(state->cli->auth->auth_ctx,
    2221                                       struct schannel_state);
    2222         struct tevent_req *subreq;
    2223 
    2224         if (schannel_auth == NULL ||
    2225             !ndr_syntax_id_equal(&state->cli->abstract_syntax,
    2226                                  &ndr_table_netlogon.syntax_id)) {
    2227                 tevent_req_done(req);
    2228                 return;
    2229         }
    2230 
    2231         ZERO_STRUCT(state->return_auth);
    2232 
    2233         state->creds = netlogon_creds_copy(state, schannel_auth->creds);
    2234         if (state->creds == NULL) {
    2235                 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
    2236                 return;
    2237         }
    2238 
    2239         netlogon_creds_client_authenticator(state->creds, &state->auth);
    2240 
    2241         state->r.in.server_name = state->cli->srv_name_slash;
    2242         state->r.in.computer_name = state->creds->computer_name;
    2243         state->r.in.credential = &state->auth;
    2244         state->r.in.query_level = 1;
    2245         state->r.in.return_authenticator = &state->return_auth;
    2246 
    2247         state->r.out.capabilities = &state->capabilities;
    2248         state->r.out.return_authenticator = &state->return_auth;
    2249 
    2250         subreq = dcerpc_netr_LogonGetCapabilities_r_send(talloc_tos(),
    2251                                                          state->ev,
    2252                                                          b,
    2253                                                          &state->r);
    2254         if (subreq == NULL) {
    2255                 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
    2256                 return;
    2257         }
    2258 
    2259         tevent_req_set_callback(subreq, rpc_pipe_bind_step_two_done, req);
    2260         return;
    2261 }
    2262 
    2263 static void rpc_pipe_bind_step_two_done(struct tevent_req *subreq)
    2264 {
    2265         struct tevent_req *req =
    2266                 tevent_req_callback_data(subreq,
    2267                                          struct tevent_req);
    2268         struct rpc_pipe_bind_state *state =
    2269                 tevent_req_data(req,
    2270                                 struct rpc_pipe_bind_state);
    2271         struct schannel_state *schannel_auth =
    2272                 talloc_get_type_abort(state->cli->auth->auth_ctx,
    2273                                       struct schannel_state);
    2274         NTSTATUS status;
    2275 
    2276         status = dcerpc_netr_LogonGetCapabilities_r_recv(subreq, talloc_tos());
    2277         TALLOC_FREE(subreq);
    2278         if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
    2279                 if (state->cli->dc->negotiate_flags &
    2280                     NETLOGON_NEG_SUPPORTS_AES) {
    2281                         DEBUG(5, ("AES is not supported and the error was %s\n",
    2282                                   nt_errstr(status)));
    2283                         tevent_req_nterror(req,
    2284                                            NT_STATUS_INVALID_NETWORK_RESPONSE);
    2285                         return;
    2286                 }
    2287 
    2288                 /* This is probably NT */
    2289                 DEBUG(5, ("We are checking against an NT - %s\n",
    2290                           nt_errstr(status)));
    2291                 tevent_req_done(req);
    2292                 return;
    2293         } else if (!NT_STATUS_IS_OK(status)) {
    2294                 DEBUG(0, ("dcerpc_netr_LogonGetCapabilities_r_recv failed with %s\n",
    2295                           nt_errstr(status)));
    2296                 tevent_req_nterror(req, status);
    2297                 return;
    2298         }
    2299 
    2300         if (NT_STATUS_EQUAL(state->r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
    2301                 if (state->creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
    2302                         /* This means AES isn't supported. */
    2303                         DEBUG(5, ("AES is not supported and the error was %s\n",
    2304                                   nt_errstr(state->r.out.result)));
    2305                         tevent_req_nterror(req,
    2306                                            NT_STATUS_INVALID_NETWORK_RESPONSE);
    2307                         return;
    2308                 }
    2309 
    2310                 /* This is probably an old Samba version */
    2311                 DEBUG(5, ("We are checking against an old Samba version - %s\n",
    2312                           nt_errstr(state->r.out.result)));
    2313                 tevent_req_done(req);
    2314                 return;
    2315         }
    2316 
    2317         /* We need to check the credential state here, cause win2k3 and earlier
    2318          * returns NT_STATUS_NOT_IMPLEMENTED */
    2319         if (!netlogon_creds_client_check(state->creds,
    2320                                          &state->r.out.return_authenticator->cred)) {
    2321                 /*
    2322                  * Server replied with bad credential. Fail.
    2323                  */
    2324                 DEBUG(0,("rpc_pipe_bind_step_two_done: server %s "
    2325                          "replied with bad credential\n",
    2326                          state->cli->desthost));
    2327                 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
    2328                 return;
    2329         }
    2330 
    2331         TALLOC_FREE(schannel_auth->creds);
    2332         schannel_auth->creds = talloc_steal(state->cli, state->creds);
    2333 
    2334         if (!NT_STATUS_IS_OK(state->r.out.result)) {
    2335                 DEBUG(0, ("dcerpc_netr_LogonGetCapabilities_r_recv failed with %s\n",
    2336                           nt_errstr(state->r.out.result)));
    2337                 tevent_req_nterror(req, state->r.out.result);
    2338                 return;
    2339         }
    2340 
    2341         if (state->creds->negotiate_flags !=
    2342             state->r.out.capabilities->server_capabilities) {
    2343                 DEBUG(0, ("The client capabilities don't match the server "
    2344                           "capabilities: local[0x%08X] remote[0x%08X]\n",
    2345                           state->creds->negotiate_flags,
    2346                           state->capabilities.server_capabilities));
    2347                 tevent_req_nterror(req,
    2348                                    NT_STATUS_INVALID_NETWORK_RESPONSE);
    2349                 return;
    2350         }
    2351 
    2352         /* TODO: Add downgrade dectection. */
    2353 
    2354         tevent_req_done(req);
    23552038        return;
    23562039}
     
    24272110{
    24282111        TALLOC_CTX *frame = talloc_stackframe();
    2429         struct event_context *ev;
     2112        struct tevent_context *ev;
    24302113        struct tevent_req *req;
    24312114        NTSTATUS status = NT_STATUS_OK;
    24322115
    2433         ev = event_context_init(frame);
     2116        ev = samba_tevent_context_init(frame);
    24342117        if (ev == NULL) {
    24352118                status = NT_STATUS_NO_MEMORY;
     
    24432126        }
    24442127
    2445         if (!tevent_req_poll(req, ev)) {
    2446                 status = map_nt_error_from_unix(errno);
     2128        if (!tevent_req_poll_ntstatus(req, ev, &status)) {
    24472129                goto fail;
    24482130        }
     
    25092191
    25102192        return rpccli_set_timeout(hs->rpc_cli, timeout);
     2193}
     2194
     2195static void rpccli_bh_auth_info(struct dcerpc_binding_handle *h,
     2196                                enum dcerpc_AuthType *auth_type,
     2197                                enum dcerpc_AuthLevel *auth_level)
     2198{
     2199        struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
     2200                                     struct rpccli_bh_state);
     2201
     2202        if (hs->rpc_cli == NULL) {
     2203                return;
     2204        }
     2205
     2206        if (hs->rpc_cli->auth == NULL) {
     2207                return;
     2208        }
     2209
     2210        *auth_type = hs->rpc_cli->auth->auth_type;
     2211        *auth_level = hs->rpc_cli->auth->auth_level;
    25112212}
    25122213
     
    25452246        ok = rpccli_bh_is_connected(h);
    25462247        if (!ok) {
    2547                 tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION);
     2248                tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
    25482249                return tevent_req_post(req, ev);
    25492250        }
     
    26282329        ok = rpccli_bh_is_connected(h);
    26292330        if (!ok) {
    2630                 tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION);
     2331                tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
    26312332                return tevent_req_post(req, ev);
    26322333        }
     
    26912392        .is_connected           = rpccli_bh_is_connected,
    26922393        .set_timeout            = rpccli_bh_set_timeout,
     2394        .auth_info              = rpccli_bh_auth_info,
    26932395        .raw_call_send          = rpccli_bh_raw_call_send,
    26942396        .raw_call_recv          = rpccli_bh_raw_call_recv,
     
    27012403
    27022404/* initialise a rpc_pipe_client binding handle */
    2703 struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c)
     2405struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c,
     2406                                        const struct GUID *object,
     2407                                        const struct ndr_interface_table *table)
    27042408{
    27052409        struct dcerpc_binding_handle *h;
     
    27082412        h = dcerpc_binding_handle_create(c,
    27092413                                         &rpccli_bh_ops,
    2710                                          NULL,
    2711                                          NULL, /* TODO */
     2414                                         object,
     2415                                         table,
    27122416                                         &hs,
    27132417                                         struct rpccli_bh_state,
     
    27212425}
    27222426
    2723 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
    2724 {
    2725         struct auth_ntlmssp_state *a = NULL;
    2726         struct cli_state *cli;
    2727 
    2728         if (rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_NTLMSSP) {
    2729                 a = talloc_get_type_abort(rpc_cli->auth->auth_ctx,
    2730                                           struct auth_ntlmssp_state);
    2731         } else if (rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_SPNEGO) {
    2732                 struct spnego_context *spnego_ctx;
    2733                 enum spnego_mech auth_type;
    2734                 void *auth_ctx;
    2735                 NTSTATUS status;
    2736 
    2737                 spnego_ctx = talloc_get_type_abort(rpc_cli->auth->auth_ctx,
    2738                                                    struct spnego_context);
    2739                 status = spnego_get_negotiated_mech(spnego_ctx,
    2740                                                     &auth_type, &auth_ctx);
    2741                 if (!NT_STATUS_IS_OK(status)) {
    2742                         return false;
    2743                 }
    2744 
    2745                 if (auth_type == SPNEGO_NTLMSSP) {
    2746                         a = talloc_get_type_abort(auth_ctx,
    2747                                                   struct auth_ntlmssp_state);
    2748                 }
    2749         }
    2750 
    2751         if (a) {
    2752                 memcpy(nt_hash, auth_ntlmssp_get_nt_hash(a), 16);
    2753                 return true;
    2754         }
    2755 
    2756         cli = rpc_pipe_np_smb_conn(rpc_cli);
    2757         if (cli == NULL) {
    2758                 return false;
    2759         }
    2760         E_md4hash(cli->password ? cli->password : "", nt_hash);
    2761         return true;
    2762 }
    2763 
    2764 NTSTATUS rpccli_ncalrpc_bind_data(TALLOC_CTX *mem_ctx,
    2765                                   struct pipe_auth_data **presult)
    2766 {
    2767         struct pipe_auth_data *result;
    2768 
    2769         result = talloc(mem_ctx, struct pipe_auth_data);
    2770         if (result == NULL) {
    2771                 return NT_STATUS_NO_MEMORY;
    2772         }
    2773 
    2774         result->auth_type = DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM;
    2775         result->auth_level = DCERPC_AUTH_LEVEL_CONNECT;
    2776         result->auth_context_id = 1;
    2777 
    2778         result->user_name = talloc_strdup(result, "");
    2779         result->domain = talloc_strdup(result, "");
    2780         if ((result->user_name == NULL) || (result->domain == NULL)) {
    2781                 TALLOC_FREE(result);
    2782                 return NT_STATUS_NO_MEMORY;
    2783         }
    2784 
    2785         *presult = result;
    2786         return NT_STATUS_OK;
    2787 }
    2788 
    27892427NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
    27902428                               struct pipe_auth_data **presult)
    27912429{
    27922430        struct pipe_auth_data *result;
    2793 
    2794         result = talloc(mem_ctx, struct pipe_auth_data);
     2431        struct auth_generic_state *auth_generic_ctx;
     2432        NTSTATUS status;
     2433
     2434        result = talloc_zero(mem_ctx, struct pipe_auth_data);
    27952435        if (result == NULL) {
    27962436                return NT_STATUS_NO_MEMORY;
     
    28012441        result->auth_context_id = 0;
    28022442
    2803         result->user_name = talloc_strdup(result, "");
    2804         result->domain = talloc_strdup(result, "");
    2805         if ((result->user_name == NULL) || (result->domain == NULL)) {
    2806                 TALLOC_FREE(result);
    2807                 return NT_STATUS_NO_MEMORY;
    2808         }
    2809 
     2443        status = auth_generic_client_prepare(result,
     2444                                             &auth_generic_ctx);
     2445        if (!NT_STATUS_IS_OK(status)) {
     2446                DEBUG(1, ("Failed to create auth_generic context: %s\n",
     2447                          nt_errstr(status)));
     2448        }
     2449
     2450        status = auth_generic_set_username(auth_generic_ctx, "");
     2451        if (!NT_STATUS_IS_OK(status)) {
     2452                DEBUG(1, ("Failed to set username: %s\n",
     2453                          nt_errstr(status)));
     2454        }
     2455
     2456        status = auth_generic_set_domain(auth_generic_ctx, "");
     2457        if (!NT_STATUS_IS_OK(status)) {
     2458                DEBUG(1, ("Failed to set domain: %s\n",
     2459                          nt_errstr(status)));
     2460                return status;
     2461        }
     2462
     2463        status = gensec_set_credentials(auth_generic_ctx->gensec_security,
     2464                                        auth_generic_ctx->credentials);
     2465        if (!NT_STATUS_IS_OK(status)) {
     2466                DEBUG(1, ("Failed to set GENSEC credentials: %s\n",
     2467                          nt_errstr(status)));
     2468                return status;
     2469        }
     2470        talloc_unlink(auth_generic_ctx, auth_generic_ctx->credentials);
     2471        auth_generic_ctx->credentials = NULL;
     2472
     2473        result->auth_ctx = talloc_move(result, &auth_generic_ctx->gensec_security);
     2474        talloc_free(auth_generic_ctx);
    28102475        *presult = result;
    28112476        return NT_STATUS_OK;
    28122477}
    28132478
    2814 static int cli_auth_ntlmssp_data_destructor(struct pipe_auth_data *auth)
    2815 {
    2816         TALLOC_FREE(auth->auth_ctx);
    2817         return 0;
    2818 }
    2819 
    2820 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
    2821                                   enum dcerpc_AuthType auth_type,
    2822                                   enum dcerpc_AuthLevel auth_level,
    2823                                   const char *domain,
    2824                                   const char *username,
    2825                                   const char *password,
    2826                                   struct pipe_auth_data **presult)
    2827 {
    2828         struct auth_ntlmssp_state *ntlmssp_ctx;
     2479static NTSTATUS rpccli_generic_bind_data(TALLOC_CTX *mem_ctx,
     2480                                         enum dcerpc_AuthType auth_type,
     2481                                         enum dcerpc_AuthLevel auth_level,
     2482                                         const char *server,
     2483                                         const char *target_service,
     2484                                         const char *domain,
     2485                                         const char *username,
     2486                                         const char *password,
     2487                                         enum credentials_use_kerberos use_kerberos,
     2488                                         struct netlogon_creds_CredentialState *creds,
     2489                                         struct pipe_auth_data **presult)
     2490{
     2491        struct auth_generic_state *auth_generic_ctx;
    28292492        struct pipe_auth_data *result;
    28302493        NTSTATUS status;
    28312494
    2832         result = talloc(mem_ctx, struct pipe_auth_data);
     2495        result = talloc_zero(mem_ctx, struct pipe_auth_data);
    28332496        if (result == NULL) {
    28342497                return NT_STATUS_NO_MEMORY;
     
    28392502        result->auth_context_id = 1;
    28402503
    2841         result->user_name = talloc_strdup(result, username);
    2842         result->domain = talloc_strdup(result, domain);
    2843         if ((result->user_name == NULL) || (result->domain == NULL)) {
    2844                 status = NT_STATUS_NO_MEMORY;
     2504        status = auth_generic_client_prepare(result,
     2505                                             &auth_generic_ctx);
     2506        if (!NT_STATUS_IS_OK(status)) {
    28452507                goto fail;
    28462508        }
    28472509
    2848         status = auth_ntlmssp_client_start(NULL,
    2849                                       global_myname(),
    2850                                       lp_workgroup(),
    2851                                       lp_client_ntlmv2_auth(),
    2852                                       &ntlmssp_ctx);
     2510        status = auth_generic_set_username(auth_generic_ctx, username);
    28532511        if (!NT_STATUS_IS_OK(status)) {
    28542512                goto fail;
    28552513        }
    28562514
    2857         talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
    2858 
    2859         status = auth_ntlmssp_set_username(ntlmssp_ctx, username);
     2515        status = auth_generic_set_domain(auth_generic_ctx, domain);
    28602516        if (!NT_STATUS_IS_OK(status)) {
    28612517                goto fail;
    28622518        }
    28632519
    2864         status = auth_ntlmssp_set_domain(ntlmssp_ctx, domain);
     2520        status = auth_generic_set_password(auth_generic_ctx, password);
    28652521        if (!NT_STATUS_IS_OK(status)) {
    28662522                goto fail;
    28672523        }
    28682524
    2869         status = auth_ntlmssp_set_password(ntlmssp_ctx, password);
     2525        status = gensec_set_target_service(auth_generic_ctx->gensec_security, target_service);
    28702526        if (!NT_STATUS_IS_OK(status)) {
    28712527                goto fail;
    28722528        }
    28732529
    2874         /*
    2875          * Turn off sign+seal to allow selected auth level to turn it back on.
    2876          */
    2877         auth_ntlmssp_and_flags(ntlmssp_ctx, ~(NTLMSSP_NEGOTIATE_SIGN |
    2878                                                 NTLMSSP_NEGOTIATE_SEAL));
    2879 
    2880         if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
    2881                 auth_ntlmssp_or_flags(ntlmssp_ctx, NTLMSSP_NEGOTIATE_SIGN);
    2882         } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
    2883                 auth_ntlmssp_or_flags(ntlmssp_ctx, NTLMSSP_NEGOTIATE_SEAL |
    2884                                                      NTLMSSP_NEGOTIATE_SIGN);
    2885         }
    2886 
    2887         result->auth_ctx = ntlmssp_ctx;
     2530        status = gensec_set_target_hostname(auth_generic_ctx->gensec_security, server);
     2531        if (!NT_STATUS_IS_OK(status)) {
     2532                goto fail;
     2533        }
     2534
     2535        cli_credentials_set_kerberos_state(auth_generic_ctx->credentials, use_kerberos);
     2536        cli_credentials_set_netlogon_creds(auth_generic_ctx->credentials, creds);
     2537
     2538        status = auth_generic_client_start_by_authtype(auth_generic_ctx, auth_type, auth_level);
     2539        if (!NT_STATUS_IS_OK(status)) {
     2540                goto fail;
     2541        }
     2542
     2543        result->auth_ctx = talloc_move(result, &auth_generic_ctx->gensec_security);
     2544        talloc_free(auth_generic_ctx);
    28882545        *presult = result;
    28892546        return NT_STATUS_OK;
     
    28942551}
    28952552
    2896 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
    2897                                    enum dcerpc_AuthLevel auth_level,
    2898                                    struct netlogon_creds_CredentialState *creds,
    2899                                    struct pipe_auth_data **presult)
    2900 {
    2901         struct schannel_state *schannel_auth;
     2553/* This routine steals the creds pointer that is passed in */
     2554static NTSTATUS rpccli_generic_bind_data_from_creds(TALLOC_CTX *mem_ctx,
     2555                                                    enum dcerpc_AuthType auth_type,
     2556                                                    enum dcerpc_AuthLevel auth_level,
     2557                                                    const char *server,
     2558                                                    const char *target_service,
     2559                                                    struct cli_credentials *creds,
     2560                                                    struct pipe_auth_data **presult)
     2561{
     2562        struct auth_generic_state *auth_generic_ctx;
    29022563        struct pipe_auth_data *result;
    2903 
    2904         result = talloc(mem_ctx, struct pipe_auth_data);
     2564        NTSTATUS status;
     2565
     2566        result = talloc_zero(mem_ctx, struct pipe_auth_data);
    29052567        if (result == NULL) {
    29062568                return NT_STATUS_NO_MEMORY;
    29072569        }
    29082570
    2909         result->auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
     2571        result->auth_type = auth_type;
    29102572        result->auth_level = auth_level;
    29112573        result->auth_context_id = 1;
    29122574
    2913         result->user_name = talloc_strdup(result, "");
    2914         result->domain = talloc_strdup(result, domain);
    2915         if ((result->user_name == NULL) || (result->domain == NULL)) {
     2575        status = auth_generic_client_prepare(result,
     2576                                             &auth_generic_ctx);
     2577        if (!NT_STATUS_IS_OK(status)) {
    29162578                goto fail;
    29172579        }
    29182580
    2919         schannel_auth = talloc(result, struct schannel_state);
    2920         if (schannel_auth == NULL) {
     2581        status = auth_generic_set_creds(auth_generic_ctx, creds);
     2582        if (!NT_STATUS_IS_OK(status)) {
    29212583                goto fail;
    29222584        }
    29232585
    2924         schannel_auth->state = SCHANNEL_STATE_START;
    2925         schannel_auth->seq_num = 0;
    2926         schannel_auth->initiator = true;
    2927         schannel_auth->creds = netlogon_creds_copy(result, creds);
    2928 
    2929         result->auth_ctx = schannel_auth;
     2586        status = gensec_set_target_service(auth_generic_ctx->gensec_security, target_service);
     2587        if (!NT_STATUS_IS_OK(status)) {
     2588                goto fail;
     2589        }
     2590
     2591        status = gensec_set_target_hostname(auth_generic_ctx->gensec_security, server);
     2592        if (!NT_STATUS_IS_OK(status)) {
     2593                goto fail;
     2594        }
     2595
     2596        status = auth_generic_client_start_by_authtype(auth_generic_ctx, auth_type, auth_level);
     2597        if (!NT_STATUS_IS_OK(status)) {
     2598                goto fail;
     2599        }
     2600
     2601        result->auth_ctx = talloc_move(result, &auth_generic_ctx->gensec_security);
     2602        talloc_free(auth_generic_ctx);
    29302603        *presult = result;
    29312604        return NT_STATUS_OK;
     
    29332606 fail:
    29342607        TALLOC_FREE(result);
    2935         return NT_STATUS_NO_MEMORY;
     2608        return status;
     2609}
     2610
     2611NTSTATUS rpccli_ncalrpc_bind_data(TALLOC_CTX *mem_ctx,
     2612                                  struct pipe_auth_data **presult)
     2613{
     2614        return rpccli_generic_bind_data(mem_ctx,
     2615                                        DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM,
     2616                                        DCERPC_AUTH_LEVEL_CONNECT,
     2617                                        NULL, /* server */
     2618                                        "host", /* target_service */
     2619                                        NAME_NT_AUTHORITY, /* domain */
     2620                                        "SYSTEM",
     2621                                        "", /* password */
     2622                                        CRED_DONT_USE_KERBEROS,
     2623                                        NULL, /* netlogon_creds_CredentialState */
     2624                                        presult);
    29362625}
    29372626
     
    29402629 */
    29412630static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
     2631                                       const struct sockaddr_storage *ss_addr,
    29422632                                       uint16_t port,
    2943                                        const struct ndr_syntax_id *abstract_syntax,
     2633                                       const struct ndr_interface_table *table,
    29442634                                       struct rpc_pipe_client **presult)
    29452635{
     
    29492639        int fd;
    29502640
    2951         result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
     2641        result = talloc_zero(mem_ctx, struct rpc_pipe_client);
    29522642        if (result == NULL) {
    29532643                return NT_STATUS_NO_MEMORY;
    29542644        }
    29552645
    2956         result->abstract_syntax = *abstract_syntax;
    2957         result->transfer_syntax = ndr_transfer_syntax;
     2646        result->abstract_syntax = table->syntax_id;
     2647        result->transfer_syntax = ndr_transfer_syntax_ndr;
    29582648
    29592649        result->desthost = talloc_strdup(result, host);
     
    29682658        result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
    29692659
    2970         if (!resolve_name(host, &addr, NBT_NAME_SERVER, false)) {
    2971                 status = NT_STATUS_NOT_FOUND;
    2972                 goto fail;
     2660        if (ss_addr == NULL) {
     2661                if (!resolve_name(host, &addr, NBT_NAME_SERVER, false)) {
     2662                        status = NT_STATUS_NOT_FOUND;
     2663                        goto fail;
     2664                }
     2665        } else {
     2666                addr = *ss_addr;
    29732667        }
    29742668
     
    29872681        result->transport->transport = NCACN_IP_TCP;
    29882682
    2989         result->binding_handle = rpccli_bh_create(result);
     2683        result->binding_handle = rpccli_bh_create(result, NULL, table);
    29902684        if (result->binding_handle == NULL) {
    29912685                TALLOC_FREE(result);
     
    30072701 */
    30082702static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
    3009                                       const struct ndr_syntax_id *abstract_syntax,
     2703                                      const struct sockaddr_storage *addr,
     2704                                      const struct ndr_interface_table *table,
    30102705                                      uint16_t *pport)
    30112706{
     
    30162711        struct dcerpc_binding *map_binding = NULL;
    30172712        struct dcerpc_binding *res_binding = NULL;
     2713        enum dcerpc_transport_t transport;
     2714        const char *endpoint = NULL;
    30182715        struct epm_twr_t *map_tower = NULL;
    30192716        struct epm_twr_t *res_towers = NULL;
     
    30302727        }
    30312728
    3032         if (ndr_syntax_id_equal(abstract_syntax,
     2729        if (ndr_syntax_id_equal(&table->syntax_id,
    30332730                                &ndr_table_epmapper.syntax_id)) {
    30342731                *pport = 135;
    3035                 return NT_STATUS_OK;
     2732                status = NT_STATUS_OK;
     2733                goto done;
    30362734        }
    30372735
    30382736        /* open the connection to the endpoint mapper */
    3039         status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
    3040                                         &ndr_table_epmapper.syntax_id,
     2737        status = rpc_pipe_open_tcp_port(tmp_ctx, host, addr, 135,
     2738                                        &ndr_table_epmapper,
    30412739                                        &epm_pipe);
    30422740
     
    30582756        /* create tower for asking the epmapper */
    30592757
    3060         map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
    3061         if (map_binding == NULL) {
    3062                 status = NT_STATUS_NO_MEMORY;
     2758        status = dcerpc_parse_binding(tmp_ctx, "ncacn_ip_tcp:[135]",
     2759                                      &map_binding);
     2760        if (!NT_STATUS_IS_OK(status)) {
    30632761                goto done;
    30642762        }
    30652763
    3066         map_binding->transport = NCACN_IP_TCP;
    3067         map_binding->object = *abstract_syntax;
    3068         map_binding->host = host; /* needed? */
    3069         map_binding->endpoint = "0"; /* correct? needed? */
    3070 
    3071         map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
     2764        status = dcerpc_binding_set_abstract_syntax(map_binding,
     2765                                                    &table->syntax_id);
     2766        if (!NT_STATUS_IS_OK(status)) {
     2767                goto done;
     2768        }
     2769
     2770        map_tower = talloc_zero(tmp_ctx, struct epm_twr_t);
    30722771        if (map_tower == NULL) {
    30732772                status = NT_STATUS_NO_MEMORY;
     
    30832782        /* allocate further parameters for the epm_Map call */
    30842783
    3085         res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
     2784        res_towers = talloc_array(tmp_ctx, struct epm_twr_t, max_towers);
    30862785        if (res_towers == NULL) {
    30872786                status = NT_STATUS_NO_MEMORY;
     
    30902789        towers.twr = res_towers;
    30912790
    3092         entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
     2791        entry_handle = talloc_zero(tmp_ctx, struct policy_handle);
    30932792        if (entry_handle == NULL) {
    30942793                status = NT_STATUS_NO_MEMORY;
     
    31002799        status = dcerpc_epm_Map(epm_handle,
    31012800                                tmp_ctx,
    3102                                 CONST_DISCARD(struct GUID *,
    3103                                               &(abstract_syntax->uuid)),
     2801                                discard_const_p(struct GUID,
     2802                                              &(table->syntax_id.uuid)),
    31042803                                map_tower,
    31052804                                entry_handle,
     
    31322831        }
    31332832
     2833        transport = dcerpc_binding_get_transport(res_binding);
     2834        endpoint = dcerpc_binding_get_string_option(res_binding, "endpoint");
     2835
    31342836        /* are further checks here necessary? */
    3135         if (res_binding->transport != NCACN_IP_TCP) {
    3136                 status = NT_STATUS_UNSUCCESSFUL;
     2837        if (transport != NCACN_IP_TCP) {
     2838                status = NT_STATUS_INVALID_NETWORK_RESPONSE;
    31372839                goto done;
    31382840        }
    31392841
    3140         *pport = (uint16_t)atoi(res_binding->endpoint);
     2842        if (endpoint == NULL) {
     2843                status = NT_STATUS_INVALID_NETWORK_RESPONSE;
     2844                goto done;
     2845        }
     2846
     2847        *pport = (uint16_t)atoi(endpoint);
    31412848
    31422849done:
     
    31512858 */
    31522859NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
    3153                            const struct ndr_syntax_id *abstract_syntax,
     2860                           const struct sockaddr_storage *addr,
     2861                           const struct ndr_interface_table *table,
    31542862                           struct rpc_pipe_client **presult)
    31552863{
     
    31572865        uint16_t port = 0;
    31582866
    3159         status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
     2867        status = rpc_pipe_get_tcp_port(host, addr, table, &port);
    31602868        if (!NT_STATUS_IS_OK(status)) {
    31612869                return status;
    31622870        }
    31632871
    3164         return rpc_pipe_open_tcp_port(mem_ctx, host, port,
    3165                                         abstract_syntax, presult);
     2872        return rpc_pipe_open_tcp_port(mem_ctx, host, addr, port,
     2873                                      table, presult);
    31662874}
    31672875
     
    31702878 ********************************************************************/
    31712879NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
    3172                                const struct ndr_syntax_id *abstract_syntax,
     2880                               const struct ndr_interface_table *table,
    31732881                               struct rpc_pipe_client **presult)
    31742882{
     
    31772885        NTSTATUS status;
    31782886        int fd;
     2887        socklen_t salen;
    31792888
    31802889        result = talloc_zero(mem_ctx, struct rpc_pipe_client);
     
    31832892        }
    31842893
    3185         result->abstract_syntax = *abstract_syntax;
    3186         result->transfer_syntax = ndr_transfer_syntax;
     2894        result->abstract_syntax = table->syntax_id;
     2895        result->transfer_syntax = ndr_transfer_syntax_ndr;
    31872896
    31882897        result->desthost = get_myname(result);
     
    32062915        addr.sun_family = AF_UNIX;
    32072916        strlcpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
    3208 
    3209         if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
     2917        salen = sizeof(struct sockaddr_un);
     2918
     2919        if (connect(fd, (struct sockaddr *)(void *)&addr, salen) == -1) {
    32102920                DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
    32112921                          strerror(errno)));
     
    32222932        result->transport->transport = NCALRPC;
    32232933
    3224         result->binding_handle = rpccli_bh_create(result);
     2934        result->binding_handle = rpccli_bh_create(result, NULL, table);
    32252935        if (result->binding_handle == NULL) {
    32262936                TALLOC_FREE(result);
     
    32612971
    32622972static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
    3263                                  const struct ndr_syntax_id *abstract_syntax,
     2973                                 const struct ndr_interface_table *table,
    32642974                                 struct rpc_pipe_client **presult)
    32652975{
     
    32742984        }
    32752985
    3276         result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
     2986        result = talloc_zero(NULL, struct rpc_pipe_client);
    32772987        if (result == NULL) {
    32782988                return NT_STATUS_NO_MEMORY;
    32792989        }
    32802990
    3281         result->abstract_syntax = *abstract_syntax;
    3282         result->transfer_syntax = ndr_transfer_syntax;
    3283         result->desthost = talloc_strdup(result, cli->desthost);
     2991        result->abstract_syntax = table->syntax_id;
     2992        result->transfer_syntax = ndr_transfer_syntax_ndr;
     2993        result->desthost = talloc_strdup(result, smbXcli_conn_remote_name(cli->conn));
    32842994        result->srv_name_slash = talloc_asprintf_strupper_m(
    32852995                result, "\\\\%s", result->desthost);
     
    32933003        }
    32943004
    3295         status = rpc_transport_np_init(result, cli, abstract_syntax,
     3005        status = rpc_transport_np_init(result, cli, table,
    32963006                                       &result->transport);
    32973007        if (!NT_STATUS_IS_OK(status)) {
     
    33133023        talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
    33143024
    3315         result->binding_handle = rpccli_bh_create(result);
     3025        result->binding_handle = rpccli_bh_create(result, NULL, table);
    33163026        if (result->binding_handle == NULL) {
    33173027                TALLOC_FREE(result);
     
    33293039static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
    33303040                                  enum dcerpc_transport_t transport,
    3331                                   const struct ndr_syntax_id *interface,
     3041                                  const struct ndr_interface_table *table,
    33323042                                  struct rpc_pipe_client **presult)
    33333043{
    33343044        switch (transport) {
    33353045        case NCACN_IP_TCP:
    3336                 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
    3337                                          presult);
     3046                return rpc_pipe_open_tcp(NULL,
     3047                                         smbXcli_conn_remote_name(cli->conn),
     3048                                         smbXcli_conn_remote_sockaddr(cli->conn),
     3049                                         table, presult);
    33383050        case NCACN_NP:
    3339                 return rpc_pipe_open_np(cli, interface, presult);
     3051                return rpc_pipe_open_np(cli, table, presult);
    33403052        default:
    33413053                return NT_STATUS_NOT_IMPLEMENTED;
     
    33493061NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
    33503062                                            enum dcerpc_transport_t transport,
    3351                                             const struct ndr_syntax_id *interface,
     3063                                            const struct ndr_interface_table *table,
    33523064                                            struct rpc_pipe_client **presult)
    33533065{
     
    33563068        NTSTATUS status;
    33573069
    3358         status = cli_rpc_pipe_open(cli, transport, interface, &result);
     3070        status = cli_rpc_pipe_open(cli, transport, table, &result);
    33593071        if (!NT_STATUS_IS_OK(status)) {
    33603072                return status;
     
    33753087         */
    33763088
    3377         TALLOC_FREE(auth->user_name);
    3378         TALLOC_FREE(auth->domain);
    3379 
    3380         auth->user_name = talloc_strdup(auth, cli->user_name);
    3381         auth->domain = talloc_strdup(auth, cli->domain);
    3382         auth->user_session_key = data_blob_talloc(auth,
    3383                 cli->user_session_key.data,
    3384                 cli->user_session_key.length);
    3385 
    3386         if ((auth->user_name == NULL) || (auth->domain == NULL)) {
    3387                 TALLOC_FREE(result);
    3388                 return NT_STATUS_NO_MEMORY;
     3089        if (transport == NCACN_NP) {
     3090                struct smbXcli_session *session;
     3091
     3092                if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
     3093                        session = cli->smb2.session;
     3094                } else {
     3095                        session = cli->smb1.session;
     3096                }
     3097
     3098                status = smbXcli_session_application_key(session, auth,
     3099                                                &auth->transport_session_key);
     3100                if (!NT_STATUS_IS_OK(status)) {
     3101                        auth->transport_session_key = data_blob_null;
     3102                }
    33893103        }
    33903104
     
    33923106        if (!NT_STATUS_IS_OK(status)) {
    33933107                int lvl = 0;
    3394                 if (ndr_syntax_id_equal(interface,
     3108                if (ndr_syntax_id_equal(&table->syntax_id,
    33953109                                        &ndr_table_dssetup.syntax_id)) {
    33963110                        /* non AD domains just don't have this pipe, avoid
     
    34003114                DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
    34013115                            "%s failed with error %s\n",
    3402                             get_pipe_name_from_syntax(talloc_tos(), interface),
     3116                            table->name,
    34033117                            nt_errstr(status) ));
    34043118                TALLOC_FREE(result);
     
    34083122        DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
    34093123                  "%s and bound anonymously.\n",
    3410                   get_pipe_name_from_syntax(talloc_tos(), interface),
    3411                   cli->desthost));
     3124                  table->name,
     3125                  result->desthost));
    34123126
    34133127        *presult = result;
     
    34193133
    34203134NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
    3421                                   const struct ndr_syntax_id *interface,
     3135                                  const struct ndr_interface_table *table,
    34223136                                  struct rpc_pipe_client **presult)
    34233137{
    34243138        return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
    3425                                                   interface, presult);
     3139                                                  table, presult);
    34263140}
    34273141
    34283142/****************************************************************************
    3429  Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
     3143 Open a named pipe to an SMB server and bind using the mech specified
     3144
     3145 This routine references the creds pointer that is passed in
    34303146 ****************************************************************************/
    34313147
    3432 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
    3433                                    const struct ndr_syntax_id *interface,
    3434                                    enum dcerpc_transport_t transport,
    3435                                    enum dcerpc_AuthLevel auth_level,
    3436                                    const char *domain,
    3437                                    const char *username,
    3438                                    const char *password,
    3439                                    struct rpc_pipe_client **presult)
     3148NTSTATUS cli_rpc_pipe_open_with_creds(struct cli_state *cli,
     3149                                      const struct ndr_interface_table *table,
     3150                                      enum dcerpc_transport_t transport,
     3151                                      enum dcerpc_AuthType auth_type,
     3152                                      enum dcerpc_AuthLevel auth_level,
     3153                                      const char *server,
     3154                                      struct cli_credentials *creds,
     3155                                      struct rpc_pipe_client **presult)
    34403156{
    34413157        struct rpc_pipe_client *result;
    34423158        struct pipe_auth_data *auth = NULL;
    3443         enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
    3444         NTSTATUS status;
    3445 
    3446         status = cli_rpc_pipe_open(cli, transport, interface, &result);
     3159        const char *target_service = table->authservices->names[0];
     3160
     3161        NTSTATUS status;
     3162
     3163        status = cli_rpc_pipe_open(cli, transport, table, &result);
    34473164        if (!NT_STATUS_IS_OK(status)) {
    34483165                return status;
    34493166        }
    34503167
    3451         status = rpccli_ntlmssp_bind_data(result,
    3452                                           auth_type, auth_level,
    3453                                           domain, username, password,
    3454                                           &auth);
    3455         if (!NT_STATUS_IS_OK(status)) {
    3456                 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
     3168        status = rpccli_generic_bind_data_from_creds(result,
     3169                                                     auth_type, auth_level,
     3170                                                     server, target_service,
     3171                                                     creds,
     3172                                                     &auth);
     3173        if (!NT_STATUS_IS_OK(status)) {
     3174                DEBUG(0, ("rpccli_generic_bind_data returned %s\n",
    34573175                          nt_errstr(status)));
    34583176                goto err;
     
    34613179        status = rpc_pipe_bind(result, auth);
    34623180        if (!NT_STATUS_IS_OK(status)) {
    3463                 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
     3181                DEBUG(0, ("cli_rpc_pipe_open_generic_auth: cli_rpc_pipe_bind failed with error %s\n",
    34643182                        nt_errstr(status) ));
    34653183                goto err;
    34663184        }
    34673185
    3468         DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
    3469                 "machine %s and bound NTLMSSP as user %s\\%s.\n",
    3470                   get_pipe_name_from_syntax(talloc_tos(), interface),
    3471                   cli->desthost, domain, username ));
     3186        DEBUG(10,("cli_rpc_pipe_open_generic_auth: opened pipe %s to "
     3187                "machine %s and bound as user %s.\n", table->name,
     3188                  result->desthost, cli_credentials_get_unparsed_name(creds, talloc_tos())));
    34723189
    34733190        *presult = result;
     
    34813198
    34823199/****************************************************************************
    3483  External interface.
    3484  Open a named pipe to an SMB server and bind using schannel (bind type 68)
    3485  using session_key. sign and seal.
    3486 
    3487  The *pdc will be stolen onto this new pipe
     3200 Open a named pipe to an SMB server and bind using the mech specified
     3201
     3202 This routine steals the creds pointer that is passed in
    34883203 ****************************************************************************/
    34893204
    3490 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
    3491                                              const struct ndr_syntax_id *interface,
    3492                                              enum dcerpc_transport_t transport,
    3493                                              enum dcerpc_AuthLevel auth_level,
    3494                                              const char *domain,
    3495                                              struct netlogon_creds_CredentialState **pdc,
    3496                                              struct rpc_pipe_client **presult)
    3497 {
    3498         struct rpc_pipe_client *result;
    3499         struct pipe_auth_data *auth;
    3500         NTSTATUS status;
    3501 
    3502         status = cli_rpc_pipe_open(cli, transport, interface, &result);
    3503         if (!NT_STATUS_IS_OK(status)) {
    3504                 return status;
    3505         }
    3506 
    3507         status = rpccli_schannel_bind_data(result, domain, auth_level,
    3508                                            *pdc, &auth);
    3509         if (!NT_STATUS_IS_OK(status)) {
    3510                 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
    3511                           nt_errstr(status)));
    3512                 TALLOC_FREE(result);
    3513                 return status;
    3514         }
    3515 
    3516         status = rpc_pipe_bind(result, auth);
    3517         if (!NT_STATUS_IS_OK(status)) {
    3518                 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
    3519                           "cli_rpc_pipe_bind failed with error %s\n",
    3520                           nt_errstr(status) ));
    3521                 TALLOC_FREE(result);
    3522                 return status;
    3523         }
    3524 
    3525         /*
    3526          * The credentials on a new netlogon pipe are the ones we are passed
    3527          * in - copy them over
    3528          */
    3529         result->dc = netlogon_creds_copy(result, *pdc);
    3530         if (result->dc == NULL) {
    3531                 TALLOC_FREE(result);
    3532                 return NT_STATUS_NO_MEMORY;
    3533         }
    3534 
    3535         DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
    3536                   "for domain %s and bound using schannel.\n",
    3537                   get_pipe_name_from_syntax(talloc_tos(), interface),
    3538                   cli->desthost, domain ));
    3539 
    3540         *presult = result;
    3541         return NT_STATUS_OK;
    3542 }
    3543 
    3544 /****************************************************************************
    3545  Open a named pipe to an SMB server and bind using krb5 (bind type 16).
    3546  The idea is this can be called with service_princ, username and password all
    3547  NULL so long as the caller has a TGT.
    3548  ****************************************************************************/
    3549 
    3550 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
    3551                                 const struct ndr_syntax_id *interface,
    3552                                 enum dcerpc_transport_t transport,
    3553                                 enum dcerpc_AuthLevel auth_level,
    3554                                 const char *server,
    3555                                 const char *username,
    3556                                 const char *password,
    3557                                 struct rpc_pipe_client **presult)
    3558 {
    3559         struct rpc_pipe_client *result;
    3560         struct pipe_auth_data *auth;
    3561         struct gse_context *gse_ctx;
    3562         NTSTATUS status;
    3563 
    3564         status = cli_rpc_pipe_open(cli, transport, interface, &result);
    3565         if (!NT_STATUS_IS_OK(status)) {
    3566                 return status;
    3567         }
    3568 
    3569         auth = talloc(result, struct pipe_auth_data);
    3570         if (auth == NULL) {
    3571                 status = NT_STATUS_NO_MEMORY;
    3572                 goto err_out;
    3573         }
    3574         auth->auth_type = DCERPC_AUTH_TYPE_KRB5;
    3575         auth->auth_level = auth_level;
    3576         auth->auth_context_id = 1;
    3577 
    3578         if (!username) {
    3579                 username = "";
    3580         }
    3581         auth->user_name = talloc_strdup(auth, username);
    3582         if (!auth->user_name) {
    3583                 status = NT_STATUS_NO_MEMORY;
    3584                 goto err_out;
    3585         }
    3586 
    3587         /* Fixme, should we fetch/set the Realm ? */
    3588         auth->domain = talloc_strdup(auth, "");
    3589         if (!auth->domain) {
    3590                 status = NT_STATUS_NO_MEMORY;
    3591                 goto err_out;
    3592         }
    3593 
    3594         status = gse_init_client(auth,
    3595                                  (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY),
    3596                                  (auth_level == DCERPC_AUTH_LEVEL_PRIVACY),
    3597                                  NULL, server, "cifs", username, password,
    3598                                  GSS_C_DCE_STYLE, &gse_ctx);
    3599         if (!NT_STATUS_IS_OK(status)) {
    3600                 DEBUG(0, ("gse_init_client returned %s\n",
    3601                           nt_errstr(status)));
    3602                 goto err_out;
    3603         }
    3604         auth->auth_ctx = gse_ctx;
    3605 
    3606         status = rpc_pipe_bind(result, auth);
    3607         if (!NT_STATUS_IS_OK(status)) {
    3608                 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
    3609                           nt_errstr(status)));
    3610                 goto err_out;
    3611         }
    3612 
    3613         *presult = result;
    3614         return NT_STATUS_OK;
    3615 
    3616 err_out:
    3617         TALLOC_FREE(result);
    3618         return status;
    3619 }
    3620 
    3621 NTSTATUS cli_rpc_pipe_open_spnego_krb5(struct cli_state *cli,
    3622                                         const struct ndr_syntax_id *interface,
     3205NTSTATUS cli_rpc_pipe_open_generic_auth(struct cli_state *cli,
     3206                                        const struct ndr_interface_table *table,
    36233207                                        enum dcerpc_transport_t transport,
     3208                                        enum credentials_use_kerberos use_kerberos,
     3209                                        enum dcerpc_AuthType auth_type,
    36243210                                        enum dcerpc_AuthLevel auth_level,
    36253211                                        const char *server,
     3212                                        const char *domain,
    36263213                                        const char *username,
    36273214                                        const char *password,
     
    36293216{
    36303217        struct rpc_pipe_client *result;
    3631         struct pipe_auth_data *auth;
    3632         struct spnego_context *spnego_ctx;
    3633         NTSTATUS status;
    3634 
    3635         status = cli_rpc_pipe_open(cli, transport, interface, &result);
     3218        struct pipe_auth_data *auth = NULL;
     3219        const char *target_service = table->authservices->names[0];
     3220       
     3221        NTSTATUS status;
     3222
     3223        status = cli_rpc_pipe_open(cli, transport, table, &result);
    36363224        if (!NT_STATUS_IS_OK(status)) {
    36373225                return status;
    36383226        }
    36393227
    3640         auth = talloc(result, struct pipe_auth_data);
    3641         if (auth == NULL) {
    3642                 status = NT_STATUS_NO_MEMORY;
    3643                 goto err_out;
    3644         }
    3645         auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
    3646         auth->auth_level = auth_level;
    3647         auth->auth_context_id = 1;
    3648 
    3649         if (!username) {
    3650                 username = "";
    3651         }
    3652         auth->user_name = talloc_strdup(auth, username);
    3653         if (!auth->user_name) {
    3654                 status = NT_STATUS_NO_MEMORY;
    3655                 goto err_out;
    3656         }
    3657 
    3658         /* Fixme, should we fetch/set the Realm ? */
    3659         auth->domain = talloc_strdup(auth, "");
    3660         if (!auth->domain) {
    3661                 status = NT_STATUS_NO_MEMORY;
    3662                 goto err_out;
    3663         }
    3664 
    3665         status = spnego_gssapi_init_client(auth,
    3666                                            (auth->auth_level ==
    3667                                                 DCERPC_AUTH_LEVEL_INTEGRITY),
    3668                                            (auth->auth_level ==
    3669                                                 DCERPC_AUTH_LEVEL_PRIVACY),
    3670                                            true,
    3671                                            NULL, server, "cifs",
    3672                                            username, password,
    3673                                            &spnego_ctx);
    3674         if (!NT_STATUS_IS_OK(status)) {
    3675                 DEBUG(0, ("spnego_init_client returned %s\n",
     3228        status = rpccli_generic_bind_data(result,
     3229                                          auth_type, auth_level,
     3230                                          server, target_service,
     3231                                          domain, username, password,
     3232                                          CRED_AUTO_USE_KERBEROS,
     3233                                          NULL,
     3234                                          &auth);
     3235        if (!NT_STATUS_IS_OK(status)) {
     3236                DEBUG(0, ("rpccli_generic_bind_data returned %s\n",
    36763237                          nt_errstr(status)));
    3677                 goto err_out;
    3678         }
    3679         auth->auth_ctx = spnego_ctx;
     3238                goto err;
     3239        }
    36803240
    36813241        status = rpc_pipe_bind(result, auth);
    36823242        if (!NT_STATUS_IS_OK(status)) {
    3683                 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
    3684                           nt_errstr(status)));
    3685                 goto err_out;
    3686         }
     3243                DEBUG(0, ("cli_rpc_pipe_open_generic_auth: cli_rpc_pipe_bind failed with error %s\n",
     3244                        nt_errstr(status) ));
     3245                goto err;
     3246        }
     3247
     3248        DEBUG(10,("cli_rpc_pipe_open_generic_auth: opened pipe %s to "
     3249                "machine %s and bound as user %s\\%s.\n", table->name,
     3250                  result->desthost, domain, username));
    36873251
    36883252        *presult = result;
    36893253        return NT_STATUS_OK;
    36903254
    3691 err_out:
     3255  err:
     3256
    36923257        TALLOC_FREE(result);
    36933258        return status;
    36943259}
    36953260
    3696 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
    3697                                           const struct ndr_syntax_id *interface,
    3698                                           enum dcerpc_transport_t transport,
    3699                                           enum dcerpc_AuthLevel auth_level,
    3700                                           const char *domain,
    3701                                           const char *username,
    3702                                           const char *password,
    3703                                           struct rpc_pipe_client **presult)
    3704 {
    3705         struct rpc_pipe_client *result;
    3706         struct pipe_auth_data *auth;
    3707         struct spnego_context *spnego_ctx;
    3708         NTSTATUS status;
    3709 
    3710         status = cli_rpc_pipe_open(cli, transport, interface, &result);
     3261NTSTATUS cli_rpc_pipe_open_schannel_with_creds(struct cli_state *cli,
     3262                                               const struct ndr_interface_table *table,
     3263                                               enum dcerpc_transport_t transport,
     3264                                               struct cli_credentials *cli_creds,
     3265                                               struct netlogon_creds_cli_context *netlogon_creds,
     3266                                               struct rpc_pipe_client **_rpccli)
     3267{
     3268        struct rpc_pipe_client *rpccli;
     3269        struct pipe_auth_data *rpcauth;
     3270        const char *target_service = table->authservices->names[0];
     3271        struct netlogon_creds_CredentialState *ncreds = NULL;
     3272        enum dcerpc_AuthLevel auth_level;
     3273        NTSTATUS status;
     3274        int rpc_pipe_bind_dbglvl = 0;
     3275
     3276        status = cli_rpc_pipe_open(cli, transport, table, &rpccli);
    37113277        if (!NT_STATUS_IS_OK(status)) {
    37123278                return status;
    37133279        }
    37143280
    3715         auth = talloc(result, struct pipe_auth_data);
    3716         if (auth == NULL) {
    3717                 status = NT_STATUS_NO_MEMORY;
    3718                 goto err_out;
    3719         }
    3720         auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
    3721         auth->auth_level = auth_level;
    3722         auth->auth_context_id = 1;
    3723 
    3724         if (!username) {
    3725                 username = "";
    3726         }
    3727         auth->user_name = talloc_strdup(auth, username);
    3728         if (!auth->user_name) {
    3729                 status = NT_STATUS_NO_MEMORY;
    3730                 goto err_out;
    3731         }
    3732 
    3733         if (!domain) {
    3734                 domain = "";
    3735         }
    3736         auth->domain = talloc_strdup(auth, domain);
    3737         if (!auth->domain) {
    3738                 status = NT_STATUS_NO_MEMORY;
    3739                 goto err_out;
    3740         }
    3741 
    3742         status = spnego_ntlmssp_init_client(auth,
    3743                                             (auth->auth_level ==
    3744                                                 DCERPC_AUTH_LEVEL_INTEGRITY),
    3745                                             (auth->auth_level ==
    3746                                                 DCERPC_AUTH_LEVEL_PRIVACY),
    3747                                             true,
    3748                                             domain, username, password,
    3749                                             &spnego_ctx);
    3750         if (!NT_STATUS_IS_OK(status)) {
    3751                 DEBUG(0, ("spnego_init_client returned %s\n",
     3281        status = netlogon_creds_cli_lock(netlogon_creds, rpccli, &ncreds);
     3282        if (!NT_STATUS_IS_OK(status)) {
     3283                DEBUG(0, ("netlogon_creds_cli_get returned %s\n",
    37523284                          nt_errstr(status)));
    3753                 goto err_out;
    3754         }
    3755         auth->auth_ctx = spnego_ctx;
    3756 
    3757         status = rpc_pipe_bind(result, auth);
    3758         if (!NT_STATUS_IS_OK(status)) {
    3759                 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
     3285                TALLOC_FREE(rpccli);
     3286                return status;
     3287        }
     3288
     3289        auth_level = netlogon_creds_cli_auth_level(netlogon_creds);
     3290
     3291        cli_credentials_set_netlogon_creds(cli_creds, ncreds);
     3292
     3293        status = rpccli_generic_bind_data_from_creds(rpccli,
     3294                                                     DCERPC_AUTH_TYPE_SCHANNEL,
     3295                                                     auth_level,
     3296                                                     rpccli->desthost,
     3297                                                     target_service,
     3298                                                     cli_creds,
     3299                                                     &rpcauth);
     3300        if (!NT_STATUS_IS_OK(status)) {
     3301                DEBUG(0, ("rpccli_generic_bind_data_from_creds returned %s\n",
    37603302                          nt_errstr(status)));
    3761                 goto err_out;
    3762         }
    3763 
    3764         *presult = result;
     3303                TALLOC_FREE(rpccli);
     3304                return status;
     3305        }
     3306
     3307        status = rpc_pipe_bind(rpccli, rpcauth);
     3308        cli_credentials_set_netlogon_creds(cli_creds, NULL);
     3309        if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
     3310                rpc_pipe_bind_dbglvl = 1;
     3311                netlogon_creds_cli_delete(netlogon_creds, &ncreds);
     3312        }
     3313        if (!NT_STATUS_IS_OK(status)) {
     3314                DEBUG(rpc_pipe_bind_dbglvl,
     3315                      ("%s: rpc_pipe_bind failed with error %s\n",
     3316                       __func__, nt_errstr(status)));
     3317                TALLOC_FREE(rpccli);
     3318                return status;
     3319        }
     3320
     3321        TALLOC_FREE(ncreds);
     3322
     3323        if (!ndr_syntax_id_equal(&table->syntax_id, &ndr_table_netlogon.syntax_id)) {
     3324                goto done;
     3325        }
     3326
     3327        status = netlogon_creds_cli_check(netlogon_creds,
     3328                                          rpccli->binding_handle);
     3329        if (!NT_STATUS_IS_OK(status)) {
     3330                DEBUG(0, ("netlogon_creds_cli_check failed with %s\n",
     3331                          nt_errstr(status)));
     3332                TALLOC_FREE(rpccli);
     3333                return status;
     3334        }
     3335
     3336
     3337done:
     3338        DEBUG(10,("%s: opened pipe %s to machine %s "
     3339                  "for domain %s and bound using schannel.\n",
     3340                  __func__, table->name,
     3341                  rpccli->desthost, cli_credentials_get_domain(cli_creds)));
     3342
     3343        *_rpccli = rpccli;
    37653344        return NT_STATUS_OK;
    3766 
    3767 err_out:
    3768         TALLOC_FREE(result);
    3769         return status;
    37703345}
    37713346
     
    37743349                             DATA_BLOB *session_key)
    37753350{
    3776         struct pipe_auth_data *a = cli->auth;
    3777         struct schannel_state *schannel_auth;
    3778         struct auth_ntlmssp_state *ntlmssp_ctx;
    3779         struct spnego_context *spnego_ctx;
    3780         struct gse_context *gse_ctx;
     3351        NTSTATUS status;
     3352        struct pipe_auth_data *a;
     3353        struct gensec_security *gensec_security;
    37813354        DATA_BLOB sk = data_blob_null;
    37823355        bool make_dup = false;
     
    37863359        }
    37873360
    3788         if (!cli->auth) {
     3361        a = cli->auth;
     3362
     3363        if (a == NULL) {
    37893364                return NT_STATUS_INVALID_PARAMETER;
    37903365        }
    37913366
    37923367        switch (cli->auth->auth_type) {
    3793         case DCERPC_AUTH_TYPE_SCHANNEL:
    3794                 schannel_auth = talloc_get_type_abort(a->auth_ctx,
    3795                                                       struct schannel_state);
    3796                 sk = data_blob_const(schannel_auth->creds->session_key, 16);
    3797                 make_dup = true;
    3798                 break;
    3799         case DCERPC_AUTH_TYPE_SPNEGO:
    3800                 spnego_ctx = talloc_get_type_abort(a->auth_ctx,
    3801                                                    struct spnego_context);
    3802                 sk = spnego_get_session_key(mem_ctx, spnego_ctx);
    3803                 make_dup = false;
    3804                 break;
    3805         case DCERPC_AUTH_TYPE_NTLMSSP:
    3806                 ntlmssp_ctx = talloc_get_type_abort(a->auth_ctx,
    3807                                                     struct auth_ntlmssp_state);
    3808                 sk = auth_ntlmssp_get_session_key(ntlmssp_ctx);
    3809                 make_dup = true;
    3810                 break;
    3811         case DCERPC_AUTH_TYPE_KRB5:
    3812                 gse_ctx = talloc_get_type_abort(a->auth_ctx,
    3813                                                 struct gse_context);
    3814                 sk = gse_get_session_key(mem_ctx, gse_ctx);
    3815                 make_dup = false;
    3816                 break;
    3817         case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
    38183368        case DCERPC_AUTH_TYPE_NONE:
    3819                 sk = data_blob_const(a->user_session_key.data,
    3820                                      a->user_session_key.length);
     3369                sk = data_blob_const(a->transport_session_key.data,
     3370                                     a->transport_session_key.length);
    38213371                make_dup = true;
    38223372                break;
    38233373        default:
     3374                gensec_security = a->auth_ctx;
     3375                status = gensec_session_key(gensec_security, mem_ctx, &sk);
     3376                if (!NT_STATUS_IS_OK(status)) {
     3377                        return status;
     3378                }
     3379                make_dup = false;
    38243380                break;
    38253381        }
     
    38303386
    38313387        if (make_dup) {
    3832                 *session_key = data_blob_dup_talloc(mem_ctx, &sk);
     3388                *session_key = data_blob_dup_talloc(mem_ctx, sk);
    38333389        } else {
    38343390                *session_key = sk;
  • vendor/current/source3/rpc_client/cli_pipe.h

    r740 r988  
    2525
    2626#include "rpc_client/rpc_client.h"
     27#include "auth/credentials/credentials.h"
    2728
    2829/* The following definitions come from rpc_client/cli_pipe.c  */
    2930
    30 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
    31                                          struct event_context *ev,
    32                                          struct rpc_pipe_client *cli,
    33                                          uint8_t op_num,
    34                                          DATA_BLOB *req_data);
    35 
    36 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req,
    37                                TALLOC_CTX *mem_ctx,
    38                                DATA_BLOB *reply_pdu);
    39 
    4031struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
    41                                       struct event_context *ev,
     32                                      struct tevent_context *ev,
    4233                                      struct rpc_pipe_client *cli,
    4334                                      struct pipe_auth_data *auth);
     
    5344bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli);
    5445
    55 bool rpccli_get_pwd_hash(struct rpc_pipe_client *cli, uint8_t nt_hash[16]);
    56 
    5746NTSTATUS rpccli_ncalrpc_bind_data(TALLOC_CTX *mem_ctx,
    5847                                  struct pipe_auth_data **presult);
     
    6150                               struct pipe_auth_data **presult);
    6251
    63 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx,
    64                                    const char *domain,
    65                                    enum dcerpc_AuthLevel auth_level,
    66                                    struct netlogon_creds_CredentialState *creds,
    67                                    struct pipe_auth_data **presult);
    68 
    6952NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx,
    7053                           const char *host,
    71                            const struct ndr_syntax_id *abstract_syntax,
     54                           const struct sockaddr_storage *ss_addr,
     55                           const struct ndr_interface_table *table,
    7256                           struct rpc_pipe_client **presult);
    7357
    7458NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
    75                                const struct ndr_syntax_id *abstract_syntax,
     59                               const struct ndr_interface_table *table,
    7660                               struct rpc_pipe_client **presult);
    7761
    78 struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c);
     62struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c,
     63                                        const struct GUID *object,
     64                                        const struct ndr_interface_table *table);
    7965
    8066NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
    81                                   const struct ndr_syntax_id *interface,
     67                                  const struct ndr_interface_table *table,
    8268                                  struct rpc_pipe_client **presult);
    8369
    8470NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
    8571                                            enum dcerpc_transport_t transport,
    86                                             const struct ndr_syntax_id *interface,
     72                                            const struct ndr_interface_table *table,
    8773                                            struct rpc_pipe_client **presult);
    8874
    89 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
    90                                    const struct ndr_syntax_id *interface,
    91                                    enum dcerpc_transport_t transport,
    92                                    enum dcerpc_AuthLevel auth_level,
    93                                    const char *domain,
    94                                    const char *username,
    95                                    const char *password,
    96                                    struct rpc_pipe_client **presult);
     75/****************************************************************************
     76 Open a named pipe to an SMB server and bind using the mech specified
    9777
    98 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
    99                                           const struct ndr_syntax_id *interface,
    100                                           enum dcerpc_transport_t transport,
    101                                           enum dcerpc_AuthLevel auth_level,
    102                                           const char *domain,
    103                                           const char *username,
    104                                           const char *password,
    105                                           struct rpc_pipe_client **presult);
     78 This routine steals the creds pointer that is passed in
     79 ****************************************************************************/
    10680
    107 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
    108                                              const struct ndr_syntax_id *interface,
    109                                              enum dcerpc_transport_t transport,
    110                                              enum dcerpc_AuthLevel auth_level,
    111                                              const char *domain,
    112                                              struct netlogon_creds_CredentialState **pdc,
    113                                              struct rpc_pipe_client **presult);
     81NTSTATUS cli_rpc_pipe_open_with_creds(struct cli_state *cli,
     82                                      const struct ndr_interface_table *table,
     83                                      enum dcerpc_transport_t transport,
     84                                      enum dcerpc_AuthType auth_type,
     85                                      enum dcerpc_AuthLevel auth_level,
     86                                      const char *server,
     87                                      struct cli_credentials *creds,
     88                                      struct rpc_pipe_client **presult);
    11489
    115 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
    116                                                  const struct ndr_syntax_id *interface,
    117                                                  enum dcerpc_transport_t transport,
    118                                                  enum dcerpc_AuthLevel auth_level,
    119                                                  const char *domain,
    120                                                  const char *username,
    121                                                  const char *password,
    122                                                  struct rpc_pipe_client **presult);
    123 
    124 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
    125                                     const struct ndr_syntax_id *interface,
    126                                     enum dcerpc_transport_t transport,
    127                                     enum dcerpc_AuthLevel auth_level,
    128                                     const char *domain,
    129                                     struct rpc_pipe_client **presult);
    130 
    131 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
    132                                 const struct ndr_syntax_id *interface,
    133                                 enum dcerpc_transport_t transport,
    134                                 enum dcerpc_AuthLevel auth_level,
    135                                 const char *service_princ,
    136                                 const char *username,
    137                                 const char *password,
    138                                 struct rpc_pipe_client **presult);
    139 
    140 NTSTATUS cli_rpc_pipe_open_spnego_krb5(struct cli_state *cli,
    141                                         const struct ndr_syntax_id *interface,
     90NTSTATUS cli_rpc_pipe_open_generic_auth(struct cli_state *cli,
     91                                        const struct ndr_interface_table *table,
    14292                                        enum dcerpc_transport_t transport,
     93                                        enum credentials_use_kerberos use_kerberos,
     94                                        enum dcerpc_AuthType auth_type,
    14395                                        enum dcerpc_AuthLevel auth_level,
    14496                                        const char *server,
     97                                        const char *domain,
    14598                                        const char *username,
    14699                                        const char *password,
    147100                                        struct rpc_pipe_client **presult);
     101
     102NTSTATUS cli_rpc_pipe_open_schannel_with_creds(struct cli_state *cli,
     103                                               const struct ndr_interface_table *table,
     104                                               enum dcerpc_transport_t transport,
     105                                               struct cli_credentials *cli_creds,
     106                                               struct netlogon_creds_cli_context *netlogon_creds,
     107                                               struct rpc_pipe_client **_rpccli);
     108
     109NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
     110                                    struct messaging_context *msg_ctx,
     111                                    const struct ndr_interface_table *table,
     112                                    enum dcerpc_transport_t transport,
     113                                    const char *domain,
     114                                    struct rpc_pipe_client **presult,
     115                                    TALLOC_CTX *mem_ctx,
     116                                    struct netlogon_creds_cli_context **pcreds);
    148117
    149118NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
     
    151120                             DATA_BLOB *session_key);
    152121
    153 /* The following definitions come from rpc_client/cli_pipe_schannel.c  */
    154 
    155 NTSTATUS get_schannel_session_key(struct cli_state *cli,
    156                                   const char *domain,
    157                                   uint32 *pneg_flags,
    158                                   struct rpc_pipe_client **presult);
    159 
    160122#endif /* _CLI_PIPE_H */
    161123
  • vendor/current/source3/rpc_client/cli_pipe_schannel.c

    r740 r988  
    2424#include "rpc_client/cli_netlogon.h"
    2525#include "rpc_client/cli_pipe.h"
    26 #include "librpc/gen_ndr/ndr_dcerpc.h"
    2726#include "librpc/rpc/dcerpc.h"
    2827#include "passdb.h"
    29 #include "client.h"
     28#include "libsmb/libsmb.h"
     29#include "../libcli/smb/smbXcli_base.h"
     30#include "libcli/auth/netlogon_creds_cli.h"
    3031
    3132#undef DBGC_CLASS
    3233#define DBGC_CLASS DBGC_RPC_CLI
    33 
    34 
    35 /****************************************************************************
    36   Get a the schannel session key out of an already opened netlogon pipe.
    37  ****************************************************************************/
    38 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
    39                                                 struct cli_state *cli,
    40                                                 const char *domain,
    41                                                 uint32 *pneg_flags)
    42 {
    43         enum netr_SchannelType sec_chan_type = 0;
    44         unsigned char machine_pwd[16];
    45         const char *machine_account;
    46         NTSTATUS status;
    47 
    48         /* Get the machine account credentials from secrets.tdb. */
    49         if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
    50                                &sec_chan_type))
    51         {
    52                 DEBUG(0, ("get_schannel_session_key: could not fetch "
    53                         "trust account password for domain '%s'\n",
    54                         domain));
    55                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
    56         }
    57 
    58         status = rpccli_netlogon_setup_creds(netlogon_pipe,
    59                                         cli->desthost, /* server name */
    60                                         domain,        /* domain */
    61                                         global_myname(), /* client name */
    62                                         machine_account, /* machine account name */
    63                                         machine_pwd,
    64                                         sec_chan_type,
    65                                         pneg_flags);
    66 
    67         if (!NT_STATUS_IS_OK(status)) {
    68                 DEBUG(3, ("get_schannel_session_key_common: "
    69                           "rpccli_netlogon_setup_creds failed with result %s "
    70                           "to server %s, domain %s, machine account %s.\n",
    71                           nt_errstr(status), cli->desthost, domain,
    72                           machine_account ));
    73                 return status;
    74         }
    75 
    76         if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
    77                 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
    78                         cli->desthost));
    79                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
    80         }
    81 
    82         return NT_STATUS_OK;
    83 }
    84 
    85 /****************************************************************************
    86  Open a named pipe to an SMB server and bind using schannel (bind type 68).
    87  Fetch the session key ourselves using a temporary netlogon pipe. This
    88  version uses an ntlmssp auth bound netlogon pipe to get the key.
    89  ****************************************************************************/
    90 
    91 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
    92                                                       const char *domain,
    93                                                       const char *username,
    94                                                       const char *password,
    95                                                       uint32 *pneg_flags,
    96                                                       struct rpc_pipe_client **presult)
    97 {
    98         struct rpc_pipe_client *netlogon_pipe = NULL;
    99         NTSTATUS status;
    100 
    101         status = cli_rpc_pipe_open_spnego_ntlmssp(
    102                 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
    103                 DCERPC_AUTH_LEVEL_PRIVACY,
    104                 domain, username, password, &netlogon_pipe);
    105         if (!NT_STATUS_IS_OK(status)) {
    106                 return status;
    107         }
    108 
    109         status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
    110                                                  pneg_flags);
    111         if (!NT_STATUS_IS_OK(status)) {
    112                 TALLOC_FREE(netlogon_pipe);
    113                 return status;
    114         }
    115 
    116         *presult = netlogon_pipe;
    117         return NT_STATUS_OK;
    118 }
    119 
    120 /****************************************************************************
    121  Open a named pipe to an SMB server and bind using schannel (bind type 68).
    122  Fetch the session key ourselves using a temporary netlogon pipe. This version
    123  uses an ntlmssp bind to get the session key.
    124  ****************************************************************************/
    125 
    126 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
    127                                                  const struct ndr_syntax_id *interface,
    128                                                  enum dcerpc_transport_t transport,
    129                                                  enum dcerpc_AuthLevel auth_level,
    130                                                  const char *domain,
    131                                                  const char *username,
    132                                                  const char *password,
    133                                                  struct rpc_pipe_client **presult)
    134 {
    135         uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
    136         struct rpc_pipe_client *netlogon_pipe = NULL;
    137         struct rpc_pipe_client *result = NULL;
    138         NTSTATUS status;
    139 
    140         status = get_schannel_session_key_auth_ntlmssp(
    141                 cli, domain, username, password, &neg_flags, &netlogon_pipe);
    142         if (!NT_STATUS_IS_OK(status)) {
    143                 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
    144                         "key from server %s for domain %s.\n",
    145                         cli->desthost, domain ));
    146                 return status;
    147         }
    148 
    149         status = cli_rpc_pipe_open_schannel_with_key(
    150                 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
    151                 &result);
    152 
    153         /* Now we've bound using the session key we can close the netlog pipe. */
    154         TALLOC_FREE(netlogon_pipe);
    155 
    156         if (NT_STATUS_IS_OK(status)) {
    157                 *presult = result;
    158         }
    159         return status;
    160 }
    16134
    16235/****************************************************************************
     
    16639
    16740NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
    168                                     const struct ndr_syntax_id *interface,
     41                                    struct messaging_context *msg_ctx,
     42                                    const struct ndr_interface_table *table,
    16943                                    enum dcerpc_transport_t transport,
    170                                     enum dcerpc_AuthLevel auth_level,
    17144                                    const char *domain,
    172                                     struct rpc_pipe_client **presult)
     45                                    struct rpc_pipe_client **presult,
     46                                    TALLOC_CTX *mem_ctx,
     47                                    struct netlogon_creds_cli_context **pcreds)
    17348{
    174         uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
    175         struct rpc_pipe_client *netlogon_pipe = NULL;
     49        TALLOC_CTX *frame = talloc_stackframe();
     50        const char *dc_name = smbXcli_conn_remote_name(cli->conn);
    17651        struct rpc_pipe_client *result = NULL;
    17752        NTSTATUS status;
     53        struct cli_credentials *cli_creds = NULL;
     54        struct netlogon_creds_cli_context *netlogon_creds = NULL;
     55        struct netlogon_creds_CredentialState *creds = NULL;
     56        uint32_t netlogon_flags;
    17857
    179         status = get_schannel_session_key(cli, domain, &neg_flags,
    180                                           &netlogon_pipe);
     58        status = pdb_get_trust_credentials(domain, NULL,
     59                                           frame, &cli_creds);
    18160        if (!NT_STATUS_IS_OK(status)) {
    182                 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
    183                         "key from server %s for domain %s.\n",
    184                         cli->desthost, domain ));
     61                TALLOC_FREE(frame);
    18562                return status;
    18663        }
    18764
    188         status = cli_rpc_pipe_open_schannel_with_key(
    189                 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
    190                 &result);
    191 
    192         /* Now we've bound using the session key we can close the netlog pipe. */
    193         TALLOC_FREE(netlogon_pipe);
    194 
    195         if (NT_STATUS_IS_OK(status)) {
    196                 *presult = result;
    197         }
    198 
    199         return status;
    200 }
    201 
    202 /****************************************************************************
    203  Open a netlogon pipe and get the schannel session key.
    204  Now exposed to external callers.
    205  ****************************************************************************/
    206 
    207 
    208 NTSTATUS get_schannel_session_key(struct cli_state *cli,
    209                                   const char *domain,
    210                                   uint32 *pneg_flags,
    211                                   struct rpc_pipe_client **presult)
    212 {
    213         struct rpc_pipe_client *netlogon_pipe = NULL;
    214         NTSTATUS status;
    215 
    216         status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
    217                                           &netlogon_pipe);
     65        status = rpccli_create_netlogon_creds_with_creds(cli_creds,
     66                                                         dc_name,
     67                                                         msg_ctx,
     68                                                         frame,
     69                                                         &netlogon_creds);
    21870        if (!NT_STATUS_IS_OK(status)) {
     71                TALLOC_FREE(frame);
    21972                return status;
    22073        }
    22174
    222         status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
    223                                                  pneg_flags);
     75        status = rpccli_setup_netlogon_creds_with_creds(cli, transport,
     76                                             netlogon_creds,
     77                                             false, /* force_reauth */
     78                                             cli_creds);
    22479        if (!NT_STATUS_IS_OK(status)) {
    225                 TALLOC_FREE(netlogon_pipe);
     80                TALLOC_FREE(frame);
    22681                return status;
    22782        }
    22883
    229         *presult = netlogon_pipe;
     84        status = netlogon_creds_cli_get(netlogon_creds, frame, &creds);
     85        if (!NT_STATUS_IS_OK(status)) {
     86                TALLOC_FREE(frame);
     87                return status;
     88        }
     89
     90        netlogon_flags = creds->negotiate_flags;
     91        TALLOC_FREE(creds);
     92
     93        if (netlogon_flags & NETLOGON_NEG_AUTHENTICATED_RPC) {
     94                status = cli_rpc_pipe_open_schannel_with_creds(cli, table,
     95                                                               transport,
     96                                                               cli_creds,
     97                                                               netlogon_creds,
     98                                                               &result);
     99                if (!NT_STATUS_IS_OK(status)) {
     100                        TALLOC_FREE(frame);
     101                        return status;
     102                }
     103        } else {
     104                status = cli_rpc_pipe_open_noauth(cli, table, &result);
     105                if (!NT_STATUS_IS_OK(status)) {
     106                        TALLOC_FREE(frame);
     107                        return status;
     108                }
     109        }
     110
     111        *presult = result;
     112        if (pcreds != NULL) {
     113                *pcreds = talloc_move(mem_ctx, &netlogon_creds);
     114        }
     115
     116        TALLOC_FREE(frame);
    230117        return NT_STATUS_OK;
    231118}
  • vendor/current/source3/rpc_client/cli_spoolss.c

    r740 r988  
    2727#include "../librpc/gen_ndr/ndr_spoolss_c.h"
    2828#include "rpc_client/cli_spoolss.h"
     29#include "auth/gensec/gensec.h"
     30#include "auth/credentials/credentials.h"
    2931
    3032/**********************************************************************
     
    4143        WERROR werror;
    4244        struct spoolss_DevmodeContainer devmode_ctr;
    43         union spoolss_UserLevel userlevel;
     45        struct spoolss_UserLevelCtr userlevel_ctr;
    4446        struct spoolss_UserLevel1 level1;
    4547        struct dcerpc_binding_handle *b = cli->binding_handle;
     48        struct cli_credentials *creds = gensec_get_credentials(cli->auth->auth_ctx);
    4649
    4750        ZERO_STRUCT(devmode_ctr);
    4851
    4952        level1.size     = 28;
    50         level1.client   = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
     53        level1.client   = talloc_asprintf(mem_ctx, "\\\\%s", lp_netbios_name());
    5154        W_ERROR_HAVE_NO_MEMORY(level1.client);
    52         level1.user     = cli->auth->user_name;
     55        level1.user     = cli_credentials_get_username(creds);
    5356        level1.build    = 1381;
    5457        level1.major    = 2;
     
    5659        level1.processor = 0;
    5760
    58         userlevel.level1 = &level1;
     61        userlevel_ctr.level = 1;
     62        userlevel_ctr.user_info.level1 = &level1;
    5963
    6064        status = dcerpc_spoolss_OpenPrinterEx(b, mem_ctx,
     
    6367                                              devmode_ctr,
    6468                                              access_desired,
    65                                               1, /* level */
    66                                               userlevel,
     69                                              userlevel_ctr,
    6770                                              handle,
    6871                                              &werror);
     
    222225        struct policy_handle handle;
    223226        struct dcerpc_binding_handle *b = cli->binding_handle;
     227        struct cli_credentials *creds = gensec_get_credentials(cli->auth->auth_ctx);
    224228
    225229        ZERO_STRUCT(devmode_ctr);
     
    231235        level1.minor            = 0;
    232236        level1.processor        = 0;
    233         level1.client           = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
     237        level1.client           = talloc_asprintf(mem_ctx, "\\\\%s", lp_netbios_name());
    234238        W_ERROR_HAVE_NO_MEMORY(level1.client);
    235         level1.user             = cli->auth->user_name;
     239        level1.user             = cli_credentials_get_username(creds);
    236240
    237241        userlevel_ctr.level = 1;
  • vendor/current/source3/rpc_client/cli_winreg.c

    r740 r988  
    3737        uint32_t value_len = 0;
    3838        uint32_t data_size = 0;
    39         WERROR result = WERR_OK;
    4039        NTSTATUS status;
    4140        DATA_BLOB blob;
     
    5150                                          &data_size,
    5251                                          &value_len,
    53                                           &result);
    54         if (!NT_STATUS_IS_OK(status)) {
    55                 return status;
    56         }
    57         if (!W_ERROR_IS_OK(result)) {
    58                 *pwerr = result;
     52                                          pwerr);
     53        if (!NT_STATUS_IS_OK(status)) {
     54                return status;
     55        }
     56        if (!W_ERROR_IS_OK(*pwerr)) {
    5957                return status;
    6058        }
    6159
    6260        if (type != REG_DWORD) {
    63                 *pwerr = WERR_INVALID_DATATYPE;
    64                 return status;
     61                return NT_STATUS_OBJECT_TYPE_MISMATCH;
    6562        }
    6663
    6764        if (data_size != 4) {
    68                 *pwerr = WERR_INVALID_DATA;
    69                 return status;
     65                return NT_STATUS_INVALID_PARAMETER;
    7066        }
    7167
    7268        blob = data_blob_talloc_zero(mem_ctx, data_size);
    7369        if (blob.data == NULL) {
    74                 *pwerr = WERR_NOMEM;
    75                 return status;
     70                return NT_STATUS_NO_MEMORY;
    7671        }
    7772        value_len = 0;
     
    8580                                          &data_size,
    8681                                          &value_len,
    87                                           &result);
    88         if (!NT_STATUS_IS_OK(status)) {
    89                 return status;
    90         }
    91         if (!W_ERROR_IS_OK(result)) {
    92                 *pwerr = result;
     82                                          pwerr);
     83        if (!NT_STATUS_IS_OK(status)) {
     84                return status;
     85        }
     86        if (!W_ERROR_IS_OK(*pwerr)) {
    9387                return status;
    9488        }
     
    110104        struct winreg_String wvalue;
    111105        enum winreg_Type type = REG_NONE;
    112         WERROR result = WERR_OK;
    113106        uint32_t value_len = 0;
    114107        uint32_t data_size = 0;
     
    127120                                          &data_size,
    128121                                          &value_len,
    129                                           &result);
    130         if (!NT_STATUS_IS_OK(status)) {
    131                 return status;
    132         }
    133         if (!W_ERROR_IS_OK(result)) {
    134                 *pwerr = result;
     122                                          pwerr);
     123        if (!NT_STATUS_IS_OK(status)) {
     124                return status;
     125        }
     126        if (!W_ERROR_IS_OK(*pwerr)) {
    135127                return status;
    136128        }
    137129
    138130        if (type != REG_BINARY) {
    139                 *pwerr = WERR_INVALID_DATATYPE;
    140                 return status;
     131                return NT_STATUS_OBJECT_TYPE_MISMATCH;
    141132        }
    142133
    143134        blob = data_blob_talloc_zero(mem_ctx, data_size);
    144135        if (blob.data == NULL) {
    145                 *pwerr = WERR_NOMEM;
    146                 return status;
     136                return NT_STATUS_NO_MEMORY;
    147137        }
    148138        value_len = 0;
     
    156146                                          &data_size,
    157147                                          &value_len,
    158                                           &result);
    159         if (!NT_STATUS_IS_OK(status)) {
    160                 return status;
    161         }
    162         if (!W_ERROR_IS_OK(result)) {
    163                 *pwerr = result;
     148                                          pwerr);
     149        if (!NT_STATUS_IS_OK(status)) {
     150                return status;
     151        }
     152        if (!W_ERROR_IS_OK(*pwerr)) {
    164153                return status;
    165154        }
     
    182171        struct winreg_String wvalue;
    183172        enum winreg_Type type = REG_NONE;
    184         WERROR result = WERR_OK;
    185173        uint32_t value_len = 0;
    186174        uint32_t data_size = 0;
     
    198186                                          &data_size,
    199187                                          &value_len,
    200                                           &result);
    201         if (!NT_STATUS_IS_OK(status)) {
    202                 return status;
    203         }
    204         if (!W_ERROR_IS_OK(result)) {
    205                 *pwerr = result;
     188                                          pwerr);
     189        if (!NT_STATUS_IS_OK(status)) {
     190                return status;
     191        }
     192        if (!W_ERROR_IS_OK(*pwerr)) {
    206193                return status;
    207194        }
    208195
    209196        if (type != REG_MULTI_SZ) {
    210                 *pwerr = WERR_INVALID_DATATYPE;
    211                 return status;
     197                return NT_STATUS_OBJECT_TYPE_MISMATCH;
    212198        }
    213199
    214200        blob = data_blob_talloc_zero(mem_ctx, data_size);
    215201        if (blob.data == NULL) {
    216                 *pwerr = WERR_NOMEM;
    217                 return status;
     202                return NT_STATUS_NO_MEMORY;
    218203        }
    219204        value_len = 0;
     
    227212                                          &data_size,
    228213                                          &value_len,
    229                                           &result);
    230         if (!NT_STATUS_IS_OK(status)) {
    231                 return status;
    232         }
    233         if (!W_ERROR_IS_OK(result)) {
    234                 *pwerr = result;
     214                                          pwerr);
     215        if (!NT_STATUS_IS_OK(status)) {
     216                return status;
     217        }
     218        if (!W_ERROR_IS_OK(*pwerr)) {
    235219                return status;
    236220        }
     
    241225                ok = pull_reg_multi_sz(mem_ctx, &blob, data);
    242226                if (!ok) {
    243                         *pwerr = WERR_NOMEM;
     227                        status = NT_STATUS_NO_MEMORY;
    244228                }
    245229        }
     
    257241        struct winreg_String wvalue;
    258242        enum winreg_Type type = REG_NONE;
    259         WERROR result = WERR_OK;
    260243        uint32_t value_len = 0;
    261244        uint32_t data_size = 0;
     
    273256                                          &data_size,
    274257                                          &value_len,
    275                                           &result);
    276         if (!NT_STATUS_IS_OK(status)) {
    277                 return status;
    278         }
    279         if (!W_ERROR_IS_OK(result)) {
    280                 *pwerr = result;
     258                                          pwerr);
     259        if (!NT_STATUS_IS_OK(status)) {
     260                return status;
     261        }
     262        if (!W_ERROR_IS_OK(*pwerr)) {
    281263                return status;
    282264        }
    283265
    284266        if (type != REG_SZ) {
    285                 *pwerr = WERR_INVALID_DATATYPE;
    286                 return status;
     267                return NT_STATUS_OBJECT_TYPE_MISMATCH;
    287268        }
    288269
    289270        blob = data_blob_talloc_zero(mem_ctx, data_size);
    290271        if (blob.data == NULL) {
    291                 *pwerr = WERR_NOMEM;
    292                 return status;
     272                return NT_STATUS_NO_MEMORY;
    293273        }
    294274        value_len = 0;
     
    302282                                          &data_size,
    303283                                          &value_len,
    304                                           &result);
    305         if (!NT_STATUS_IS_OK(status)) {
    306                 return status;
    307         }
    308         if (!W_ERROR_IS_OK(result)) {
    309                 *pwerr = result;
     284                                          pwerr);
     285        if (!NT_STATUS_IS_OK(status)) {
     286                return status;
     287        }
     288        if (!W_ERROR_IS_OK(*pwerr)) {
    310289                return status;
    311290        }
     
    316295                ok = pull_reg_sz(mem_ctx, &blob, data);
    317296                if (!ok) {
    318                         *pwerr = WERR_NOMEM;
     297                        status = NT_STATUS_NO_MEMORY;
    319298                }
    320299        }
     
    330309                                WERROR *pwerr)
    331310{
    332         WERROR result = WERR_OK;
    333311        NTSTATUS status;
    334312        DATA_BLOB blob;
     
    339317                                            value,
    340318                                            &blob,
    341                                             &result);
    342         if (!NT_STATUS_IS_OK(status)) {
    343                 return status;
    344         }
    345         if (!W_ERROR_IS_OK(result)) {
    346                 *pwerr = result;
     319                                            pwerr);
     320        if (!NT_STATUS_IS_OK(status)) {
     321                return status;
     322        }
     323        if (!W_ERROR_IS_OK(*pwerr)) {
    347324                return status;
    348325        }
     
    354331                sd = talloc_zero(mem_ctx, struct security_descriptor);
    355332                if (sd == NULL) {
    356                         *pwerr = WERR_NOMEM;
    357                         return NT_STATUS_OK;
     333                        return NT_STATUS_NO_MEMORY;
    358334                }
    359335
     
    365341                        DEBUG(2, ("dcerpc_winreg_query_sd: Failed to marshall "
    366342                                  "security descriptor\n"));
    367                         *pwerr = WERR_NOMEM;
    368                         return NT_STATUS_OK;
     343                        return NT_STATUS_NO_MEMORY;
    369344                }
    370345
     
    384359        struct winreg_String wvalue;
    385360        DATA_BLOB blob;
    386         WERROR result = WERR_OK;
    387361        NTSTATUS status;
    388362
     
    399373                                        blob.data,
    400374                                        blob.length,
    401                                         &result);
    402         if (!NT_STATUS_IS_OK(status)) {
    403                 return status;
    404         }
    405         if (!W_ERROR_IS_OK(result)) {
    406                 *pwerr = result;
    407         }
     375                                        pwerr);
    408376
    409377        return status;
     
    419387        struct winreg_String wvalue = { 0, };
    420388        DATA_BLOB blob;
    421         WERROR result = WERR_OK;
    422389        NTSTATUS status;
    423390
     
    430397                                  "string %s for %s\n",
    431398                                  data, wvalue.name));
    432                         *pwerr = WERR_NOMEM;
    433                         return NT_STATUS_OK;
     399                        return NT_STATUS_NO_MEMORY;
    434400                }
    435401        }
     
    442408                                        blob.data,
    443409                                        blob.length,
    444                                         &result);
    445         if (!NT_STATUS_IS_OK(status)) {
    446                 return status;
    447         }
    448         if (!W_ERROR_IS_OK(result)) {
    449                 *pwerr = result;
    450         }
     410                                        pwerr);
    451411
    452412        return status;
     
    462422        struct winreg_String wvalue = { 0, };
    463423        DATA_BLOB blob;
    464         WERROR result = WERR_OK;
    465424        NTSTATUS status;
    466425
     
    473432                                  "string %s for %s\n",
    474433                                  data, wvalue.name));
    475                         *pwerr = WERR_NOMEM;
    476                         return NT_STATUS_OK;
     434                        return NT_STATUS_NO_MEMORY;
    477435                }
    478436        }
     
    485443                                        blob.data,
    486444                                        blob.length,
    487                                         &result);
    488         if (!NT_STATUS_IS_OK(status)) {
    489                 return status;
    490         }
    491         if (!W_ERROR_IS_OK(result)) {
    492                 *pwerr = result;
    493         }
     445                                        pwerr);
    494446
    495447        return status;
     
    505457        struct winreg_String wvalue = { 0, };
    506458        DATA_BLOB blob;
    507         WERROR result = WERR_OK;
    508459        NTSTATUS status;
    509460
     
    513464                          "string multi sz for %s\n",
    514465                          wvalue.name));
    515                 *pwerr = WERR_NOMEM;
    516                 return NT_STATUS_OK;
     466                return NT_STATUS_NO_MEMORY;
    517467        }
    518468
     
    524474                                        blob.data,
    525475                                        blob.length,
    526                                         &result);
    527         if (!NT_STATUS_IS_OK(status)) {
    528                 return status;
    529         }
    530         if (!W_ERROR_IS_OK(result)) {
    531                 *pwerr = result;
    532         }
     476                                        pwerr);
    533477
    534478        return status;
     
    543487{
    544488        struct winreg_String wvalue = { 0, };
    545         WERROR result = WERR_OK;
    546489        NTSTATUS status;
    547490
     
    555498                                        data->data,
    556499                                        data->length,
    557                                         &result);
    558         if (!NT_STATUS_IS_OK(status)) {
    559                 return status;
    560         }
    561         if (!W_ERROR_IS_OK(result)) {
    562                 *pwerr = result;
    563         }
     500                                        pwerr);
    564501
    565502        return status;
     
    583520                DEBUG(2, ("dcerpc_winreg_set_sd: Failed to marshall security "
    584521                          "descriptor\n"));
    585                 *pwerr = WERR_NOMEM;
    586                 return NT_STATUS_OK;
     522                return NT_STATUS_NO_MEMORY;
    587523        }
    588524
     
    605541        const char **p;
    606542        uint32_t i;
    607         WERROR result = WERR_OK;
    608543        NTSTATUS status;
    609544
     
    613548                                              value,
    614549                                              &a,
    615                                               &result);
     550                                              pwerr);
    616551
    617552        /* count the elements */
    618553        for (p = a, i = 0; p && *p; p++, i++);
    619554
    620         p = TALLOC_REALLOC_ARRAY(mem_ctx, a, const char *, i + 2);
     555        p = talloc_realloc(mem_ctx, a, const char *, i + 2);
    621556        if (p == NULL) {
    622                 *pwerr = WERR_NOMEM;
    623                 return NT_STATUS_OK;
     557                return NT_STATUS_NO_MEMORY;
    624558        }
    625559
     
    651585        uint32_t secdescsize;
    652586        struct winreg_String classname;
    653         WERROR result = WERR_OK;
    654587        NTSTATUS status;
    655588        TALLOC_CTX *tmp_ctx;
     
    658591        if (tmp_ctx == NULL) {
    659592                return NT_STATUS_NO_MEMORY;
     593        }
     594
     595        ZERO_STRUCT(classname);
     596
     597        status = dcerpc_winreg_QueryInfoKey(h,
     598                                            tmp_ctx,
     599                                            key_hnd,
     600                                            &classname,
     601                                            &num_subkeys,
     602                                            &max_subkeylen,
     603                                            &max_classlen,
     604                                            &num_values,
     605                                            &max_valnamelen,
     606                                            &max_valbufsize,
     607                                            &secdescsize,
     608                                            &last_changed_time,
     609                                            pwerr);
     610        if (!NT_STATUS_IS_OK(status)) {
     611                goto error;
     612        }
     613        if (!W_ERROR_IS_OK(*pwerr)) {
     614                goto error;
     615        }
     616
     617        subkeys = talloc_zero_array(tmp_ctx, const char *, num_subkeys + 2);
     618        if (subkeys == NULL) {
     619                status = NT_STATUS_NO_MEMORY;
     620                goto error;
     621        }
     622
     623        if (num_subkeys == 0) {
     624                subkeys[0] = talloc_strdup(subkeys, "");
     625                if (subkeys[0] == NULL) {
     626                        status = NT_STATUS_NO_MEMORY;
     627                        goto error;
     628                }
     629                *pnum_subkeys = 0;
     630                if (psubkeys) {
     631                        *psubkeys = talloc_move(mem_ctx, &subkeys);
     632                }
     633
     634                TALLOC_FREE(tmp_ctx);
     635                return NT_STATUS_OK;
     636        }
     637
     638        for (i = 0; i < num_subkeys; i++) {
     639                char c = '\0';
     640                char n = '\0';
     641                char *name = NULL;
     642                struct winreg_StringBuf class_buf;
     643                struct winreg_StringBuf name_buf;
     644                NTTIME modtime;
     645
     646                class_buf.name = &c;
     647                class_buf.size = max_classlen + 2;
     648                class_buf.length = 0;
     649
     650                name_buf.name = &n;
     651                name_buf.size = max_subkeylen + 2;
     652                name_buf.length = 0;
     653
     654                ZERO_STRUCT(modtime);
     655
     656                status = dcerpc_winreg_EnumKey(h,
     657                                               tmp_ctx,
     658                                               key_hnd,
     659                                               i,
     660                                               &name_buf,
     661                                               &class_buf,
     662                                               &modtime,
     663                                               pwerr);
     664                if (!NT_STATUS_IS_OK(status)) {
     665                        DEBUG(5, ("dcerpc_winreg_enum_keys: Could not enumerate keys: %s\n",
     666                                  nt_errstr(status)));
     667                        goto error;
     668                }
     669
     670                if (W_ERROR_EQUAL(*pwerr, WERR_NO_MORE_ITEMS)) {
     671                        *pwerr = WERR_OK;
     672                        break;
     673                }
     674                if (!W_ERROR_IS_OK(*pwerr)) {
     675                        DEBUG(5, ("dcerpc_winreg_enum_keys: Could not enumerate keys: %s\n",
     676                                  win_errstr(*pwerr)));
     677                        goto error;
     678                }
     679
     680                if (name_buf.name == NULL) {
     681                        *pwerr = WERR_INVALID_PARAMETER;
     682                        goto error;
     683                }
     684
     685                name = talloc_strdup(subkeys, name_buf.name);
     686                if (name == NULL) {
     687                        status = NT_STATUS_NO_MEMORY;
     688                        goto error;
     689                }
     690
     691                subkeys[i] = name;
     692        }
     693
     694        *pnum_subkeys = num_subkeys;
     695        if (psubkeys) {
     696                *psubkeys = talloc_move(mem_ctx, &subkeys);
     697        }
     698
     699 error:
     700        TALLOC_FREE(tmp_ctx);
     701
     702        return status;
     703}
     704
     705NTSTATUS dcerpc_winreg_enumvals(TALLOC_CTX *mem_ctx,
     706                                        struct dcerpc_binding_handle *h,
     707                                        struct policy_handle *key_hnd,
     708                                        uint32_t *pnum_values,
     709                                        const char ***pnames,
     710                                        enum winreg_Type **_type,
     711                                        DATA_BLOB **pdata,
     712                                        WERROR *pwerr)
     713{
     714        TALLOC_CTX *tmp_ctx;
     715        uint32_t num_subkeys = 0, max_subkeylen = 0, max_classlen = 0;
     716        uint32_t num_values = 0, max_valnamelen = 0, max_valbufsize = 0;
     717        uint32_t secdescsize = 0;
     718        uint32_t i;
     719        NTTIME last_changed_time = 0;
     720        struct winreg_String classname;
     721
     722        const char **enum_names = NULL;
     723        enum winreg_Type *enum_types = NULL;
     724        DATA_BLOB *enum_data_blobs = NULL;
     725
     726
     727        WERROR result = WERR_OK;
     728        NTSTATUS status = NT_STATUS_OK;
     729
     730        tmp_ctx = talloc_stackframe();
     731        if (tmp_ctx == NULL) {
     732
     733                status = NT_STATUS_NO_MEMORY;
     734                *pwerr = ntstatus_to_werror(status);
     735                return status;
    660736        }
    661737
     
    676752                                            &result);
    677753        if (!NT_STATUS_IS_OK(status)) {
     754                DEBUG(0, ("dcerpc_winreg_enumvals: Could not query info: %s\n",
     755                          nt_errstr(status)));
    678756                goto error;
    679757        }
    680758        if (!W_ERROR_IS_OK(result)) {
     759                DEBUG(0, ("dcerpc_winreg_enumvals: Could not query info: %s\n",
     760                          win_errstr(result)));
    681761                *pwerr = result;
    682762                goto error;
    683763        }
    684764
    685         subkeys = talloc_zero_array(tmp_ctx, const char *, num_subkeys + 2);
    686         if (subkeys == NULL) {
     765        if (num_values == 0) {
     766                *pnum_values = 0;
     767                TALLOC_FREE(tmp_ctx);
     768                *pwerr = WERR_OK;
     769                return status;
     770        }
     771
     772        enum_names = talloc_zero_array(tmp_ctx, const char *, num_values);
     773
     774        if (enum_names == NULL) {
    687775                *pwerr = WERR_NOMEM;
    688776                goto error;
    689777        }
    690778
    691         if (num_subkeys == 0) {
    692                 subkeys[0] = talloc_strdup(subkeys, "");
    693                 if (subkeys[0] == NULL) {
    694                         *pwerr = WERR_NOMEM;
    695                         goto error;
    696                 }
    697                 *pnum_subkeys = 0;
    698                 if (psubkeys) {
    699                         *psubkeys = talloc_move(mem_ctx, &subkeys);
    700                 }
    701 
    702                 TALLOC_FREE(tmp_ctx);
    703                 return NT_STATUS_OK;
    704         }
    705 
    706         for (i = 0; i < num_subkeys; i++) {
    707                 char c = '\0';
     779        enum_types = talloc_zero_array(tmp_ctx, enum winreg_Type, num_values);
     780
     781        if (enum_types == NULL) {
     782                *pwerr = WERR_NOMEM;
     783                goto error;
     784        }
     785
     786        enum_data_blobs = talloc_zero_array(tmp_ctx, DATA_BLOB, num_values);
     787
     788        if (enum_data_blobs == NULL) {
     789                *pwerr = WERR_NOMEM;
     790                goto error;
     791        }
     792
     793        for (i = 0; i < num_values; i++) {
     794                const char *name;
     795                struct winreg_ValNameBuf name_buf;
     796                enum winreg_Type type = REG_NONE;
     797                uint8_t *data;
     798                uint32_t data_size;
     799                uint32_t length;
    708800                char n = '\0';
    709                 char *name = NULL;
    710                 struct winreg_StringBuf class_buf;
    711                 struct winreg_StringBuf name_buf;
    712                 NTTIME modtime;
    713 
    714                 class_buf.name = &c;
    715                 class_buf.size = max_classlen + 2;
    716                 class_buf.length = 0;
     801
    717802
    718803                name_buf.name = &n;
    719                 name_buf.size = max_subkeylen + 2;
     804                name_buf.size = max_valnamelen + 2;
    720805                name_buf.length = 0;
    721806
    722                 ZERO_STRUCT(modtime);
    723 
    724                 status = dcerpc_winreg_EnumKey(h,
    725                                                tmp_ctx,
    726                                                key_hnd,
    727                                                i,
    728                                                &name_buf,
    729                                                &class_buf,
    730                                                &modtime,
    731                                                &result);
     807                data_size = max_valbufsize;
     808                data = NULL;
     809                if (data_size) {
     810                        data = (uint8_t *) TALLOC(tmp_ctx, data_size);
     811                }
     812                length = 0;
     813
     814                status = dcerpc_winreg_EnumValue(h,
     815                                                 tmp_ctx,
     816                                                 key_hnd,
     817                                                 i,
     818                                                 &name_buf,
     819                                                 &type,
     820                                                 data,
     821                                                 data_size ? &data_size : NULL,
     822                                                 &length,
     823                                                 &result);
     824                if (W_ERROR_EQUAL(result, WERR_NO_MORE_ITEMS) ) {
     825                        result = WERR_OK;
     826                        status = NT_STATUS_OK;
     827                        break;
     828                }
     829
    732830                if (!NT_STATUS_IS_OK(status)) {
    733                         DEBUG(5, ("dcerpc_winreg_enum_keys: Could not enumerate keys: %s\n",
     831                        DEBUG(0, ("dcerpc_winreg_enumvals: Could not enumerate values: %s\n",
    734832                                  nt_errstr(status)));
    735833                        goto error;
    736834                }
    737 
    738                 if (W_ERROR_EQUAL(result, WERR_NO_MORE_ITEMS) ) {
    739                         *pwerr = WERR_OK;
    740                         break;
    741                 }
    742835                if (!W_ERROR_IS_OK(result)) {
    743                         DEBUG(5, ("dcerpc_winreg_enum_keys: Could not enumerate keys: %s\n",
     836                        DEBUG(0, ("dcerpc_winreg_enumvals: Could not enumerate values: %s\n",
    744837                                  win_errstr(result)));
    745838                        *pwerr = result;
     
    748841
    749842                if (name_buf.name == NULL) {
    750                         *pwerr = WERR_INVALID_PARAMETER;
     843                        result = WERR_INVALID_PARAMETER;
     844                        *pwerr = result;
    751845                        goto error;
    752846                }
    753847
    754                 name = talloc_strdup(subkeys, name_buf.name);
     848                name = talloc_strdup(enum_names, name_buf.name);
    755849                if (name == NULL) {
    756                         *pwerr = WERR_NOMEM;
     850                        result = WERR_NOMEM;
     851                        *pwerr = result;
    757852                        goto error;
    758853                }
    759 
    760                 subkeys[i] = name;
    761         }
    762 
    763         *pnum_subkeys = num_subkeys;
    764         if (psubkeys) {
    765                 *psubkeys = talloc_move(mem_ctx, &subkeys);
    766         }
     854        /* place name, type and datablob in the enum return params */
     855
     856                enum_data_blobs[i] = data_blob_talloc(enum_data_blobs, data, length);
     857                enum_names[i] = name;
     858                enum_types[i] = type;
     859
     860        }
     861        /* move to the main mem context */
     862        *pnum_values = num_values;
     863        if (pnames) {
     864                *pnames = talloc_move(mem_ctx, &enum_names);
     865        }
     866        /* can this fail in any way? */
     867        if (_type) {
     868                *_type = talloc_move(mem_ctx, &enum_types);
     869        }
     870
     871        if (pdata){
     872                *pdata = talloc_move(mem_ctx, &enum_data_blobs);
     873        }
     874
     875
     876        result = WERR_OK;
    767877
    768878 error:
    769879        TALLOC_FREE(tmp_ctx);
    770 
     880        *pwerr = result;
     881
     882        return status;
     883}
     884
     885NTSTATUS dcerpc_winreg_delete_subkeys_recursive(TALLOC_CTX *mem_ctx,
     886                                                struct dcerpc_binding_handle *h,
     887                                                struct policy_handle *hive_handle,
     888                                                uint32_t access_mask,
     889                                                const char *key,
     890                                                WERROR *pwerr)
     891{
     892        const char **subkeys = NULL;
     893        uint32_t num_subkeys = 0;
     894        struct policy_handle key_hnd;
     895        struct winreg_String wkey = { 0, };
     896        WERROR result = WERR_OK;
     897        NTSTATUS status = NT_STATUS_OK;
     898        uint32_t i;
     899
     900        ZERO_STRUCT(key_hnd);
     901        wkey.name = key;
     902
     903        DEBUG(2, ("dcerpc_winreg_delete_subkeys_recursive: delete key %s\n", key));
     904        /* open the key */
     905        status = dcerpc_winreg_OpenKey(h,
     906                                       mem_ctx,
     907                                       hive_handle,
     908                                       wkey,
     909                                       0,
     910                                       access_mask,
     911                                       &key_hnd,
     912                                       &result);
     913        if (!NT_STATUS_IS_OK(status)) {
     914                DEBUG(0, ("dcerpc_winreg_delete_subkeys_recursive: Could not open key %s: %s\n",
     915                          wkey.name, nt_errstr(status)));
     916                goto done;
     917        }
     918        if (!W_ERROR_IS_OK(result)) {
     919                DEBUG(0, ("dcerpc_winreg_delete_subkeys_recursive: Could not open key %s: %s\n",
     920                          wkey.name, win_errstr(result)));
     921                *pwerr = result;
     922                goto done;
     923        }
     924
     925        status = dcerpc_winreg_enum_keys(mem_ctx,
     926                                         h,
     927                                         &key_hnd,
     928                                         &num_subkeys,
     929                                         &subkeys,
     930                                         &result);
     931        if (!NT_STATUS_IS_OK(status)) {
     932                goto done;
     933        }
     934        if (!W_ERROR_IS_OK(result)) {
     935                goto done;
     936        }
     937
     938        for (i = 0; i < num_subkeys; i++) {
     939                /* create key + subkey */
     940                char *subkey = talloc_asprintf(mem_ctx, "%s\\%s", key, subkeys[i]);
     941                if (subkey == NULL) {
     942                        goto done;
     943                }
     944
     945                DEBUG(2, ("dcerpc_winreg_delete_subkeys_recursive: delete subkey %s\n", subkey));
     946                status = dcerpc_winreg_delete_subkeys_recursive(mem_ctx,
     947                                                                h,
     948                                                                hive_handle,
     949                                                                access_mask,
     950                                                                subkey,
     951                                                                &result);
     952                if (!W_ERROR_IS_OK(result)) {
     953                        goto done;
     954                }
     955        }
     956
     957        if (is_valid_policy_hnd(&key_hnd)) {
     958                WERROR ignore;
     959                dcerpc_winreg_CloseKey(h, mem_ctx, &key_hnd, &ignore);
     960        }
     961
     962        wkey.name = key;
     963
     964        status = dcerpc_winreg_DeleteKey(h,
     965                                         mem_ctx,
     966                                         hive_handle,
     967                                         wkey,
     968                                         &result);
     969        if (!NT_STATUS_IS_OK(status)) {
     970                *pwerr = result;
     971                goto done;
     972        }
     973
     974done:
     975        if (is_valid_policy_hnd(&key_hnd)) {
     976                WERROR ignore;
     977
     978                dcerpc_winreg_CloseKey(h, mem_ctx, &key_hnd, &ignore);
     979        }
     980
     981        *pwerr = result;
    771982        return status;
    772983}
  • vendor/current/source3/rpc_client/cli_winreg.h

    r740 r988  
    379379                                 const char ***psubkeys,
    380380                                 WERROR *pwerr);
     381/**
     382 * @internal
     383 *
     384 * @brief Enumerate values of an opened key handle and retrieve the data.
     385 *
     386 * @param[in]  mem_ctx  The memory context to use.
     387 *
     388 * @param[in]  winreg_handle The binding handle for the rpc connection.
     389 *
     390 * @param[in]  key_hnd  The opened key handle.
     391 *
     392 * @param[out] pnum_values A pointer to store the number of values we found.
     393 *
     394 * @param[out] pnames A pointer to store all the names of the values we found.
     395 *
     396 * @param[out] _type A pointer to store all the types coresponding with the
     397 *                   values found.
     398 * @param[out] pdata A pointer to store the data coresponding to the values.
     399 *
     400 * @param[out] pwerr A pointer to the WERROR. WERR_OK on success
     401 *                   WERR_OK on success, the corresponding DOS error
     402 *                   code if something's gone wrong.
     403 *
     404 * @return              NT_STATUS_OK on success or a corresponding error if
     405 *                      there was a problem on the connection.
     406 */
     407
     408NTSTATUS dcerpc_winreg_enumvals(TALLOC_CTX *mem_ctx,
     409                                        struct dcerpc_binding_handle *h,
     410                                        struct policy_handle *key_hnd,
     411                                        uint32_t *pnum_values,
     412                                        const char ***pnames,
     413                                        enum winreg_Type **_type,
     414                                        DATA_BLOB **pdata,
     415                                        WERROR *pwerr);
     416
     417/**
     418 * @internal
     419 *
     420 * @brief A function to delete a key and its subkeys recurively.
     421 *
     422 * @param[in]  mem_ctx  The memory context to use.
     423 *
     424 * @param[in]  winreg_handle The binding handle for the rpc connection.
     425 *
     426 * @param[in]  hive_handle A opened hive handle to the key.
     427 *
     428 * @param[in]  access_mask The access mask to access the key.
     429 *
     430 * @param[in]  key      The key to delete
     431 *
     432 * @param[out]          WERR_OK on success, the corresponding DOS error
     433 *                      code if something gone wrong.
     434 *
     435 * @return              NT_STATUS_OK on success or a corresponding error if
     436 *                      there was a problem on the connection.
     437 */
     438
     439NTSTATUS dcerpc_winreg_delete_subkeys_recursive(TALLOC_CTX *mem_ctx,
     440                                                struct dcerpc_binding_handle *h,
     441                                                struct policy_handle *hive_handle,
     442                                                uint32_t access_mask,
     443                                                const char *key,
     444                                                WERROR *pwerr);
     445
    381446
    382447#endif /* CLI_WINREG_H */
  • vendor/current/source3/rpc_client/cli_winreg_int.c

    r740 r988  
    2525#include "rpc_client/cli_winreg_int.h"
    2626#include "rpc_server/rpc_ncacn_np.h"
     27#include "../lib/tsocket/tsocket.h"
    2728
    2829/**
     
    8586
    8687static NTSTATUS _winreg_int_openkey(TALLOC_CTX *mem_ctx,
    87                                     const struct auth_serversupplied_info *session_info,
     88                                    const struct auth_session_info *session_info,
    8889                                    struct messaging_context *msg_ctx,
    8990                                    struct dcerpc_binding_handle **h,
     
    9697                                    WERROR *pwerr)
    9798{
    98         static struct client_address client_id;
     99        struct tsocket_address *local;
    99100        struct dcerpc_binding_handle *binding_handle;
    100101        struct winreg_String wkey, wkeyclass;
    101102        NTSTATUS status;
    102103        WERROR result = WERR_OK;
    103 
    104         strlcpy(client_id.addr, "127.0.0.1", sizeof(client_id.addr));
    105         client_id.name = "127.0.0.1";
     104        int rc;
     105
     106        rc = tsocket_address_inet_from_strings(mem_ctx,
     107                                               "ip",
     108                                               "127.0.0.1",
     109                                               0,
     110                                               &local);
     111        if (rc < 0) {
     112                return NT_STATUS_NO_MEMORY;
     113        }
    106114
    107115        status = rpcint_binding_handle(mem_ctx,
    108116                                       &ndr_table_winreg,
    109                                        &client_id,
     117                                       local,
    110118                                       session_info,
    111119                                       msg_ctx,
     
    232240
    233241NTSTATUS dcerpc_winreg_int_openkey(TALLOC_CTX *mem_ctx,
    234                                    const struct auth_serversupplied_info *server_info,
     242                                   const struct auth_session_info *server_info,
    235243                                   struct messaging_context *msg_ctx,
    236244                                   struct dcerpc_binding_handle **h,
     
    289297
    290298NTSTATUS dcerpc_winreg_int_hklm_openkey(TALLOC_CTX *mem_ctx,
    291                                         const struct auth_serversupplied_info *server_info,
     299                                        const struct auth_session_info *server_info,
    292300                                        struct messaging_context *msg_ctx,
    293301                                        struct dcerpc_binding_handle **h,
  • vendor/current/source3/rpc_client/cli_winreg_int.h

    r740 r988  
    2323#define CLI_WINREG_INT_H
    2424
    25 struct dcerpc_binding_handle;
    26 struct auth_serversupplied_info;
     25struct auth_session_info;
    2726struct dcerpc_binding_handle;
    2827
     
    5453 */
    5554NTSTATUS dcerpc_winreg_int_openkey(TALLOC_CTX *mem_ctx,
    56                                    const struct auth_serversupplied_info *server_info,
     55                                   const struct auth_session_info *server_info,
    5756                                   struct messaging_context *msg_ctx,
    5857                                   struct dcerpc_binding_handle **h,
     
    9089 */
    9190NTSTATUS dcerpc_winreg_int_hklm_openkey(TALLOC_CTX *mem_ctx,
    92                                         const struct auth_serversupplied_info *session_info,
     91                                        const struct auth_session_info *session_info,
    9392                                        struct messaging_context *msg_ctx,
    9493                                        struct dcerpc_binding_handle **h,
  • vendor/current/source3/rpc_client/cli_winreg_spoolss.c

    r746 r988  
    297297        }
    298298        if (!NT_STATUS_IS_OK(status)) {
    299                 return ntstatus_to_werror(status);
    300         }
    301         if (!W_ERROR_IS_OK(result)) {
     299                result = ntstatus_to_werror(status);
     300        }
     301        if (!W_ERROR_IS_OK(result)) {
     302                WERROR ignore;
     303
     304                if (is_valid_policy_hnd(hive_handle)) {
     305                        dcerpc_winreg_CloseKey(binding_handle,
     306                                               mem_ctx,
     307                                               hive_handle,
     308                                               &ignore);
     309                }
     310                ZERO_STRUCTP(hive_handle);
     311
    302312                return result;
    303313        }
     
    317327static char *winreg_printer_data_keyname(TALLOC_CTX *mem_ctx, const char *printer) {
    318328        return talloc_asprintf(mem_ctx, "%s\\%s", TOP_LEVEL_PRINT_PRINTERS_KEY, printer);
    319 }
    320 
    321 /**
    322  * @internal
    323  *
    324  * @brief Enumerate values of an opened key handle and retrieve the data.
    325  *
    326  * @param[in]  mem_ctx  The memory context to use.
    327  *
    328  * @param[in]  winreg_handle The binding handle for the rpc connection.
    329  *
    330  * @param[in]  key_hnd  The opened key handle.
    331  *
    332  * @param[out] pnum_values A pointer to store he number of values found.
    333  *
    334  * @param[out] pnum_values A pointer to store the number of values we found.
    335  *
    336  * @return                   WERR_OK on success, the corresponding DOS error
    337  *                           code if something gone wrong.
    338  */
    339 static WERROR winreg_printer_enumvalues(TALLOC_CTX *mem_ctx,
    340                                         struct dcerpc_binding_handle *winreg_handle,
    341                                         struct policy_handle *key_hnd,
    342                                         uint32_t *pnum_values,
    343                                         struct spoolss_PrinterEnumValues **penum_values)
    344 {
    345         TALLOC_CTX *tmp_ctx;
    346         uint32_t num_subkeys, max_subkeylen, max_classlen;
    347         uint32_t num_values, max_valnamelen, max_valbufsize;
    348         uint32_t secdescsize;
    349         uint32_t i;
    350         NTTIME last_changed_time;
    351         struct winreg_String classname;
    352 
    353         struct spoolss_PrinterEnumValues *enum_values;
    354 
    355         WERROR result = WERR_OK;
    356         NTSTATUS status;
    357 
    358         tmp_ctx = talloc_stackframe();
    359         if (tmp_ctx == NULL) {
    360                 return WERR_NOMEM;
    361         }
    362 
    363         ZERO_STRUCT(classname);
    364 
    365         status = dcerpc_winreg_QueryInfoKey(winreg_handle,
    366                                             tmp_ctx,
    367                                             key_hnd,
    368                                             &classname,
    369                                             &num_subkeys,
    370                                             &max_subkeylen,
    371                                             &max_classlen,
    372                                             &num_values,
    373                                             &max_valnamelen,
    374                                             &max_valbufsize,
    375                                             &secdescsize,
    376                                             &last_changed_time,
    377                                             &result);
    378         if (!NT_STATUS_IS_OK(status)) {
    379                 DEBUG(0, ("winreg_printer_enumvalues: Could not query info: %s\n",
    380                           nt_errstr(status)));
    381                 result = ntstatus_to_werror(status);
    382                 goto error;
    383         }
    384         if (!W_ERROR_IS_OK(result)) {
    385                 DEBUG(0, ("winreg_printer_enumvalues: Could not query info: %s\n",
    386                           win_errstr(result)));
    387                 goto error;
    388         }
    389 
    390         if (num_values == 0) {
    391                 *pnum_values = 0;
    392                 TALLOC_FREE(tmp_ctx);
    393                 return WERR_OK;
    394         }
    395 
    396         enum_values = talloc_array(tmp_ctx, struct spoolss_PrinterEnumValues, num_values);
    397         if (enum_values == NULL) {
    398                 result = WERR_NOMEM;
    399                 goto error;
    400         }
    401 
    402         for (i = 0; i < num_values; i++) {
    403                 struct spoolss_PrinterEnumValues val;
    404                 struct winreg_ValNameBuf name_buf;
    405                 enum winreg_Type type = REG_NONE;
    406                 uint8_t *data;
    407                 uint32_t data_size;
    408                 uint32_t length;
    409                 char n = '\0';
    410 
    411                 name_buf.name = &n;
    412                 name_buf.size = max_valnamelen + 2;
    413                 name_buf.length = 0;
    414 
    415                 data_size = max_valbufsize;
    416                 data = NULL;
    417                 if (data_size) {
    418                         data = (uint8_t *) talloc_zero_size(tmp_ctx, data_size);
    419                 }
    420                 length = 0;
    421 
    422                 status = dcerpc_winreg_EnumValue(winreg_handle,
    423                                                  tmp_ctx,
    424                                                  key_hnd,
    425                                                  i,
    426                                                  &name_buf,
    427                                                  &type,
    428                                                  data,
    429                                                  data_size ? &data_size : NULL,
    430                                                  &length,
    431                                                  &result);
    432                 if (W_ERROR_EQUAL(result, WERR_NO_MORE_ITEMS) ) {
    433                         result = WERR_OK;
    434                         status = NT_STATUS_OK;
    435                         break;
    436                 }
    437 
    438                 if (!NT_STATUS_IS_OK(status)) {
    439                         DEBUG(0, ("winreg_printer_enumvalues: Could not enumerate values: %s\n",
    440                                   nt_errstr(status)));
    441                         result = ntstatus_to_werror(status);
    442                         goto error;
    443                 }
    444                 if (!W_ERROR_IS_OK(result)) {
    445                         DEBUG(0, ("winreg_printer_enumvalues: Could not enumerate values: %s\n",
    446                                   win_errstr(result)));
    447                         goto error;
    448                 }
    449 
    450                 if (name_buf.name == NULL) {
    451                         result = WERR_INVALID_PARAMETER;
    452                         goto error;
    453                 }
    454 
    455                 val.value_name = talloc_strdup(enum_values, name_buf.name);
    456                 if (val.value_name == NULL) {
    457                         result = WERR_NOMEM;
    458                         goto error;
    459                 }
    460                 val.value_name_len = strlen_m_term(val.value_name) * 2;
    461 
    462                 val.type = type;
    463                 val.data_length = length;
    464                 val.data = NULL;
    465                 if (val.data_length) {
    466                         val.data = talloc(enum_values, DATA_BLOB);
    467                         if (val.data == NULL) {
    468                                 result = WERR_NOMEM;
    469                                 goto error;
    470                         }
    471                         *val.data = data_blob_talloc(val.data, data, val.data_length);
    472                 }
    473 
    474                 enum_values[i] = val;
    475         }
    476 
    477         *pnum_values = num_values;
    478         if (penum_values) {
    479                 *penum_values = talloc_move(mem_ctx, &enum_values);
    480         }
    481 
    482         result = WERR_OK;
    483 
    484  error:
    485         TALLOC_FREE(tmp_ctx);
    486         return result;
    487 }
    488 
    489 /**
    490  * @internal
    491  *
    492  * @brief A function to delete a key and its subkeys recurively.
    493  *
    494  * @param[in]  mem_ctx  The memory context to use.
    495  *
    496  * @param[in]  winreg_handle The binding handle for the rpc connection.
    497  *
    498  * @param[in]  hive_handle A opened hive handle to the key.
    499  *
    500  * @param[in]  access_mask The access mask to access the key.
    501  *
    502  * @param[in]  key      The key to delete
    503  *
    504  * @return              WERR_OK on success, the corresponding DOS error
    505  *                      code if something gone wrong.
    506  */
    507 static WERROR winreg_printer_delete_subkeys(TALLOC_CTX *mem_ctx,
    508                                             struct dcerpc_binding_handle *winreg_handle,
    509                                             struct policy_handle *hive_handle,
    510                                             uint32_t access_mask,
    511                                             const char *key)
    512 {
    513         const char **subkeys = NULL;
    514         uint32_t num_subkeys = 0;
    515         struct policy_handle key_hnd;
    516         struct winreg_String wkey = { 0, };
    517         WERROR result = WERR_OK;
    518         NTSTATUS status;
    519         uint32_t i;
    520 
    521         ZERO_STRUCT(key_hnd);
    522         wkey.name = key;
    523 
    524         DEBUG(2, ("winreg_printer_delete_subkeys: delete key %s\n", key));
    525         /* open the key */
    526         status = dcerpc_winreg_OpenKey(winreg_handle,
    527                                        mem_ctx,
    528                                        hive_handle,
    529                                        wkey,
    530                                        0,
    531                                        access_mask,
    532                                        &key_hnd,
    533                                        &result);
    534         if (!NT_STATUS_IS_OK(status)) {
    535                 DEBUG(0, ("winreg_printer_delete_subkeys: Could not open key %s: %s\n",
    536                           wkey.name, nt_errstr(status)));
    537                 return ntstatus_to_werror(status);
    538         }
    539         if (!W_ERROR_IS_OK(result)) {
    540                 DEBUG(0, ("winreg_printer_delete_subkeys: Could not open key %s: %s\n",
    541                           wkey.name, win_errstr(result)));
    542                 return result;
    543         }
    544 
    545         status = dcerpc_winreg_enum_keys(mem_ctx,
    546                                          winreg_handle,
    547                                          &key_hnd,
    548                                          &num_subkeys,
    549                                          &subkeys,
    550                                          &result);
    551         if (!NT_STATUS_IS_OK(status)) {
    552                 result = ntstatus_to_werror(status);
    553         }
    554         if (!W_ERROR_IS_OK(result)) {
    555                 goto done;
    556         }
    557 
    558         for (i = 0; i < num_subkeys; i++) {
    559                 /* create key + subkey */
    560                 char *subkey = talloc_asprintf(mem_ctx, "%s\\%s", key, subkeys[i]);
    561                 if (subkey == NULL) {
    562                         goto done;
    563                 }
    564 
    565                 DEBUG(2, ("winreg_printer_delete_subkeys: delete subkey %s\n", subkey));
    566                 result = winreg_printer_delete_subkeys(mem_ctx,
    567                                                        winreg_handle,
    568                                                        hive_handle,
    569                                                        access_mask,
    570                                                        subkey);
    571                 if (!W_ERROR_IS_OK(result)) {
    572                         goto done;
    573                 }
    574         }
    575 
    576         if (is_valid_policy_hnd(&key_hnd)) {
    577                 WERROR ignore;
    578                 dcerpc_winreg_CloseKey(winreg_handle, mem_ctx, &key_hnd, &ignore);
    579         }
    580 
    581         wkey.name = key;
    582 
    583         status = dcerpc_winreg_DeleteKey(winreg_handle,
    584                                          mem_ctx,
    585                                          hive_handle,
    586                                          wkey,
    587                                          &result);
    588         if (!NT_STATUS_IS_OK(status)) {
    589                 result = ntstatus_to_werror(status);
    590         }
    591 
    592 done:
    593         if (is_valid_policy_hnd(&key_hnd)) {
    594                 WERROR ignore;
    595 
    596                 dcerpc_winreg_CloseKey(winreg_handle, mem_ctx, &key_hnd, &ignore);
    597         }
    598 
    599         return result;
    600329}
    601330
     
    869598        uint32_t info2_mask = 0;
    870599        WERROR result = WERR_OK;
     600        WERROR ignore;
    871601        TALLOC_CTX *tmp_ctx;
    872602
     
    902632                        path, win_errstr(result)));
    903633                goto done;
     634        }
     635
     636        if (is_valid_policy_hnd(&key_hnd)) {
     637                dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
     638        }
     639        if (is_valid_policy_hnd(&hive_hnd)) {
     640                dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    904641        }
    905642
     
    982719                                                      &key_hnd,
    983720                                                      SPOOL_REG_SHORTSERVERNAME,
    984                                                       global_myname(),
     721                                                      lp_netbios_name(),
    985722                                                      &result);
    986723                        if (!NT_STATUS_IS_OK(status)) {
     
    997734                        dnssuffix = get_mydnsdomname(tmp_ctx);
    998735                        if (dnssuffix != NULL && dnssuffix[0] != '\0') {
    999                                 longname = talloc_asprintf(tmp_ctx, "%s.%s", global_myname(), dnssuffix);
     736                                longname = talloc_asprintf(tmp_ctx, "%s.%s", lp_netbios_name(), dnssuffix);
    1000737                        } else {
    1001                                 longname = talloc_strdup(tmp_ctx, global_myname());
     738                                longname = talloc_strdup(tmp_ctx, lp_netbios_name());
    1002739                        }
    1003740                        if (longname == NULL) {
     
    1172909
    1173910done:
    1174         if (winreg_handle != NULL) {
    1175                 WERROR ignore;
    1176 
    1177                 if (is_valid_policy_hnd(&key_hnd)) {
    1178                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    1179                 }
    1180                 if (is_valid_policy_hnd(&hive_hnd)) {
    1181                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    1182                 }
     911        if (is_valid_policy_hnd(&key_hnd)) {
     912                dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
     913        }
     914        if (is_valid_policy_hnd(&hive_hnd)) {
     915                dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    1183916        }
    1184917
     
    1202935        char *path;
    1203936        WERROR result = WERR_OK;
     937        WERROR ignore;
    1204938        NTSTATUS status;
    1205939        TALLOC_CTX *tmp_ctx;
     
    15841318        result = WERR_OK;
    15851319done:
    1586         if (winreg_handle != NULL) {
    1587                 WERROR ignore;
    1588 
    1589                 if (is_valid_policy_hnd(&key_hnd)) {
    1590                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    1591                 }
    1592                 if (is_valid_policy_hnd(&hive_hnd)) {
    1593                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    1594                 }
     1320        if (is_valid_policy_hnd(&key_hnd)) {
     1321                dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
     1322        }
     1323        if (is_valid_policy_hnd(&hive_hnd)) {
     1324                dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    15951325        }
    15961326
     
    16071337        uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    16081338        struct policy_handle hive_hnd, key_hnd;
    1609         struct spoolss_PrinterEnumValues *enum_values = NULL;
     1339        struct spoolss_PrinterEnumValues enum_value;
    16101340        struct spoolss_PrinterEnumValues *v = NULL;
    16111341        enum ndr_err_code ndr_err;
     
    16171347        NTSTATUS status;
    16181348        WERROR result = WERR_OK;
     1349        WERROR ignore;
     1350        const char **enum_names = NULL;
     1351        enum winreg_Type *enum_types = NULL;
     1352        DATA_BLOB *enum_data_blobs = NULL;
    16191353        TALLOC_CTX *tmp_ctx;
    16201354
     
    16441378        }
    16451379
    1646         result = winreg_printer_enumvalues(tmp_ctx,
    1647                                            winreg_handle,
    1648                                            &key_hnd,
    1649                                            &num_values,
    1650                                            &enum_values);
     1380        status = dcerpc_winreg_enumvals(tmp_ctx,
     1381                                        winreg_handle,
     1382                                        &key_hnd,
     1383                                        &num_values,
     1384                                        &enum_names,
     1385                                        &enum_types,
     1386                                        &enum_data_blobs,
     1387                                        &result);
     1388        if (!NT_STATUS_IS_OK(status)){
     1389                result = ntstatus_to_werror(status);
     1390        }
     1391
    16511392        if (!W_ERROR_IS_OK(result)) {
    16521393                DEBUG(0, ("winreg_get_printer: Could not enumerate values in %s: %s\n",
     
    16741415
    16751416        for (i = 0; i < num_values; i++) {
    1676                 v = &enum_values[i];
     1417                enum_value.value_name = enum_names[i];
     1418                enum_value.value_name_len = 2*strlen_m_term(enum_names[i]);
     1419                enum_value.type = enum_types[i];
     1420                enum_value.data_length = enum_data_blobs[i].length;
     1421                enum_value.data = NULL;
     1422                if (enum_value.data_length != 0){
     1423                        enum_value.data = &enum_data_blobs[i];
     1424                }
     1425                v = &enum_value;
    16771426
    16781427                result = winreg_enumval_to_sz(info2,
     
    18461595        result = WERR_OK;
    18471596done:
    1848         if (winreg_handle != NULL) {
    1849                 WERROR ignore;
    1850 
    1851                 if (is_valid_policy_hnd(&key_hnd)) {
    1852                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    1853                 }
    1854                 if (is_valid_policy_hnd(&hive_hnd)) {
    1855                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    1856                 }
     1597        if (is_valid_policy_hnd(&key_hnd)) {
     1598                dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
     1599        }
     1600        if (is_valid_policy_hnd(&hive_hnd)) {
     1601                dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    18571602        }
    18581603
     
    18731618        NTSTATUS status;
    18741619        WERROR result;
     1620        WERROR ignore;
    18751621
    18761622        tmp_ctx = talloc_stackframe();
     
    19141660        if (!W_ERROR_IS_OK(result)) {
    19151661                if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
     1662
     1663                        if (is_valid_policy_hnd(&key_hnd)) {
     1664                                dcerpc_winreg_CloseKey(winreg_handle,
     1665                                                       tmp_ctx,
     1666                                                       &key_hnd,
     1667                                                       &ignore);
     1668                        }
     1669
     1670                        if (is_valid_policy_hnd(&hive_hnd)) {
     1671                                dcerpc_winreg_CloseKey(winreg_handle,
     1672                                                       tmp_ctx,
     1673                                                       &hive_hnd,
     1674                                                       &ignore);
     1675                        }
    19161676                        goto create_default;
    19171677                }
     
    19971757        result = WERR_OK;
    19981758done:
    1999         if (winreg_handle != NULL) {
    2000                 WERROR ignore;
    2001 
    2002                 if (is_valid_policy_hnd(&key_hnd)) {
    2003                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    2004                 }
    2005                 if (is_valid_policy_hnd(&hive_hnd)) {
    2006                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    2007                 }
     1759        if (is_valid_policy_hnd(&key_hnd)) {
     1760                dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
     1761        }
     1762        if (is_valid_policy_hnd(&hive_hnd)) {
     1763                dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    20081764        }
    20091765
     
    20251781        NTSTATUS status;
    20261782        WERROR result;
     1783        WERROR ignore;
    20271784
    20281785        tmp_ctx = talloc_stackframe();
     
    21151872
    21161873done:
    2117         if (winreg_handle != NULL) {
    2118                 WERROR ignore;
    2119 
    2120                 if (is_valid_policy_hnd(&key_hnd)) {
    2121                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    2122                 }
    2123                 if (is_valid_policy_hnd(&hive_hnd)) {
    2124                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    2125                 }
     1874        if (is_valid_policy_hnd(&key_hnd)) {
     1875                dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
     1876        }
     1877        if (is_valid_policy_hnd(&hive_hnd)) {
     1878                dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    21261879        }
    21271880
     
    21451898        char *path;
    21461899        WERROR result = WERR_OK;
     1900        WERROR ignore;
    21471901        NTSTATUS status;
    21481902        TALLOC_CTX *tmp_ctx;
     
    21941948
    21951949done:
    2196         if (winreg_handle != NULL) {
    2197                 WERROR ignore;
    2198 
    2199                 if (is_valid_policy_hnd(&key_hnd)) {
    2200                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    2201                 }
    2202                 if (is_valid_policy_hnd(&hive_hnd)) {
    2203                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    2204                 }
     1950        if (is_valid_policy_hnd(&key_hnd)) {
     1951                dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
     1952        }
     1953        if (is_valid_policy_hnd(&hive_hnd)) {
     1954                dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    22051955        }
    22061956
     
    22281978        uint32_t value_len = 0;
    22291979        WERROR result = WERR_OK;
     1980        WERROR ignore;
    22301981        NTSTATUS status;
    22311982        TALLOC_CTX *tmp_ctx;
     
    22822033        }
    22832034        if (!W_ERROR_IS_OK(result)) {
     2035                DEBUG(2, ("winreg_get_printer_dataex: Could not query value %s: %s\n",
     2036                          value, win_errstr(result)));
    22842037                goto done;
    22852038        }
     
    23082061        }
    23092062        if (!W_ERROR_IS_OK(result)) {
     2063                DEBUG(2, ("winreg_get_printer_dataex: Could not query value %s: %s\n",
     2064                          value, win_errstr(result)));
    23102065                goto done;
    23112066        }
     
    23192074        result = WERR_OK;
    23202075done:
    2321         if (winreg_handle != NULL) {
    2322                 WERROR ignore;
    2323 
    2324                 if (is_valid_policy_hnd(&key_hnd)) {
    2325                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    2326                 }
    2327                 if (is_valid_policy_hnd(&hive_hnd)) {
    2328                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    2329                 }
     2076        if (is_valid_policy_hnd(&key_hnd)) {
     2077                dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
     2078        }
     2079        if (is_valid_policy_hnd(&hive_hnd)) {
     2080                dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    23302081        }
    23312082
     
    23422093                                  struct spoolss_PrinterEnumValues **penum_values)
    23432094{
     2095        uint32_t i;
    23442096        uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    23452097        struct policy_handle hive_hnd, key_hnd;
     
    23492101        char *path;
    23502102        WERROR result = WERR_OK;
     2103        WERROR ignore;
     2104        NTSTATUS status;
     2105        const char **enum_names = NULL;
     2106        enum winreg_Type *enum_types = NULL;
     2107        DATA_BLOB *enum_data_blobs = NULL;
    23512108
    23522109        TALLOC_CTX *tmp_ctx;
     
    23772134        }
    23782135
    2379         result = winreg_printer_enumvalues(tmp_ctx,
    2380                                            winreg_handle,
    2381                                            &key_hnd,
    2382                                            &num_values,
    2383                                            &enum_values);
     2136        status = dcerpc_winreg_enumvals(tmp_ctx,
     2137                                        winreg_handle,
     2138                                        &key_hnd,
     2139                                        &num_values,
     2140                                        &enum_names,
     2141                                        &enum_types,
     2142                                        &enum_data_blobs,
     2143                                        &result);
     2144        if (!NT_STATUS_IS_OK(status)){
     2145                result = ntstatus_to_werror(status);
     2146        }
     2147
    23842148        if (!W_ERROR_IS_OK(result)) {
    23852149                DEBUG(0, ("winreg_enum_printer_dataex: Could not enumerate values in %s: %s\n",
     
    23872151                goto done;
    23882152        }
     2153
     2154        enum_values = talloc_array(tmp_ctx, struct spoolss_PrinterEnumValues, num_values);
     2155        if (enum_values == NULL){
     2156                result = WERR_NOMEM;
     2157                DEBUG(0, ("winreg_enum_printer_dataex: Could not enumerate values in %s: %s\n",
     2158                          key, win_errstr(result)));
     2159                goto done;
     2160        }
     2161
     2162        for (i = 0; i < num_values; i++){
     2163                enum_values[i].value_name = enum_names[i];
     2164                enum_values[i].value_name_len = strlen_m_term(enum_names[i]) * 2;
     2165                enum_values[i].type = enum_types[i];
     2166                enum_values[i].data_length = enum_data_blobs[i].length;
     2167                enum_values[i].data = NULL;
     2168
     2169                if (enum_values[i].data_length != 0){
     2170                        enum_values[i].data = &enum_data_blobs[i];
     2171                }
     2172        }
     2173
     2174        talloc_steal(enum_values, enum_names);
     2175        talloc_steal(enum_values, enum_data_blobs);
    23892176
    23902177        *pnum_values = num_values;
     
    23952182        result = WERR_OK;
    23962183done:
    2397         if (winreg_handle != NULL) {
    2398                 WERROR ignore;
    2399 
    2400                 if (is_valid_policy_hnd(&key_hnd)) {
    2401                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    2402                 }
    2403                 if (is_valid_policy_hnd(&hive_hnd)) {
    2404                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    2405                 }
     2184        if (is_valid_policy_hnd(&key_hnd)) {
     2185                dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
     2186        }
     2187        if (is_valid_policy_hnd(&hive_hnd)) {
     2188                dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    24062189        }
    24072190
     
    24222205        char *path;
    24232206        WERROR result = WERR_OK;
     2207        WERROR ignore;
    24242208        NTSTATUS status;
    24252209
     
    24672251
    24682252done:
    2469         if (winreg_handle != NULL) {
    2470                 WERROR ignore;
    2471 
    2472                 if (is_valid_policy_hnd(&key_hnd)) {
    2473                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    2474                 }
    2475                 if (is_valid_policy_hnd(&hive_hnd)) {
    2476                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    2477                 }
     2253        if (is_valid_policy_hnd(&key_hnd)) {
     2254                dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
     2255        }
     2256        if (is_valid_policy_hnd(&hive_hnd)) {
     2257                dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    24782258        }
    24792259
     
    24972277
    24982278        WERROR result = WERR_OK;
     2279        WERROR ignore;
    24992280        NTSTATUS status;
    25002281
     
    25512332        result = WERR_OK;
    25522333done:
    2553         if (winreg_handle != NULL) {
    2554                 WERROR ignore;
    2555 
    2556                 if (is_valid_policy_hnd(&key_hnd)) {
    2557                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    2558                 }
    2559                 if (is_valid_policy_hnd(&hive_hnd)) {
    2560                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    2561                 }
     2334        if (is_valid_policy_hnd(&key_hnd)) {
     2335                dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
     2336        }
     2337        if (is_valid_policy_hnd(&hive_hnd)) {
     2338                dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    25622339        }
    25632340
     
    25772354        char *path;
    25782355        WERROR result;
     2356        WERROR ignore;
     2357        NTSTATUS status;
    25792358        TALLOC_CTX *tmp_ctx;
    25802359
     
    26272406        }
    26282407
    2629         result = winreg_printer_delete_subkeys(tmp_ctx,
    2630                                                winreg_handle,
    2631                                                &hive_hnd,
    2632                                                access_mask,
    2633                                                keyname);
     2408        status = dcerpc_winreg_delete_subkeys_recursive(tmp_ctx,
     2409                                                        winreg_handle,
     2410                                                        &hive_hnd,
     2411                                                        access_mask,
     2412                                                        keyname,
     2413                                                        &result);
     2414
     2415        if (!NT_STATUS_IS_OK(status)) {
     2416                DEBUG(0, ("winreg_delete_printer_key: Could not delete key %s: %s\n",
     2417                          key, nt_errstr(status)));
     2418                result = ntstatus_to_werror(status);
     2419                goto done;
     2420        }
     2421
    26342422        if (!W_ERROR_IS_OK(result)) {
    26352423                DEBUG(0, ("winreg_delete_printer_key: Could not delete key %s: %s\n",
     
    26392427
    26402428done:
    2641         if (winreg_handle != NULL) {
    2642                 WERROR ignore;
    2643 
    2644                 if (is_valid_policy_hnd(&key_hnd)) {
    2645                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    2646                 }
    2647                 if (is_valid_policy_hnd(&hive_hnd)) {
    2648                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    2649                 }
     2429        if (is_valid_policy_hnd(&key_hnd)) {
     2430                dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
     2431        }
     2432        if (is_valid_policy_hnd(&hive_hnd)) {
     2433                dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    26502434        }
    26512435
     
    26632447        NTSTATUS status;
    26642448        WERROR result;
     2449        WERROR ignore;
    26652450        TALLOC_CTX *tmp_ctx;
    26662451
     
    27082493        result = WERR_OK;
    27092494done:
    2710         if (winreg_handle != NULL) {
    2711                 WERROR ignore;
    2712 
    2713                 if (is_valid_policy_hnd(&key_hnd)) {
    2714                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    2715                 }
    2716                 if (is_valid_policy_hnd(&hive_hnd)) {
    2717                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    2718                 }
     2495        if (is_valid_policy_hnd(&key_hnd)) {
     2496                dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
     2497        }
     2498        if (is_valid_policy_hnd(&hive_hnd)) {
     2499                dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    27192500        }
    27202501
     
    27342515        NTSTATUS status;
    27352516        WERROR result;
     2517        WERROR ignore;
    27362518        TALLOC_CTX *tmp_ctx;
    27372519
     
    27852567        result = WERR_OK;
    27862568done:
    2787         if (winreg_handle != NULL) {
    2788                 WERROR ignore;
    2789 
    2790                 if (is_valid_policy_hnd(&key_hnd)) {
    2791                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    2792                 }
    2793                 if (is_valid_policy_hnd(&hive_hnd)) {
    2794                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    2795                 }
     2569        if (is_valid_policy_hnd(&key_hnd)) {
     2570                dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
     2571        }
     2572        if (is_valid_policy_hnd(&hive_hnd)) {
     2573                dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    27962574        }
    27972575
     
    28192597        uint32_t i;
    28202598        WERROR result;
     2599        WERROR ignore;
    28212600        NTSTATUS status;
    28222601        TALLOC_CTX *tmp_ctx;
     
    28872666
    28882667done:
    2889         if (winreg_handle != NULL) {
    2890                 WERROR ignore;
    2891 
    2892                 if (is_valid_policy_hnd(&key_hnd)) {
    2893                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    2894                 }
    2895                 if (is_valid_policy_hnd(&hive_hnd)) {
    2896                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    2897                 }
     2668        if (is_valid_policy_hnd(&key_hnd)) {
     2669                dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
     2670        }
     2671        if (is_valid_policy_hnd(&hive_hnd)) {
     2672                dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    28982673        }
    28992674
     
    29162691        uint32_t i;
    29172692        WERROR result;
     2693        WERROR ignore;
     2694        NTSTATUS status;
     2695        const char **enum_names = NULL;
     2696        enum winreg_Type *enum_types = NULL;
     2697        DATA_BLOB *enum_data_blobs = NULL;
    29182698        TALLOC_CTX *tmp_ctx;
    29192699
     
    29462726        }
    29472727
    2948         result = winreg_printer_enumvalues(tmp_ctx,
    2949                                            winreg_handle,
    2950                                            &key_hnd,
    2951                                            &num_values,
    2952                                            &enum_values);
     2728        status = dcerpc_winreg_enumvals(tmp_ctx,
     2729                                        winreg_handle,
     2730                                        &key_hnd,
     2731                                        &num_values,
     2732                                        &enum_names,
     2733                                        &enum_types,
     2734                                        &enum_data_blobs,
     2735                                        &result);
     2736        if (!NT_STATUS_IS_OK(status)){
     2737                result = ntstatus_to_werror(status);
     2738        }
     2739
     2740        if (!W_ERROR_IS_OK(result)) {
     2741                DEBUG(0, ("winreg_printer_enumforms1: Could not enumerate values in %s: %s\n",
     2742                          TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
     2743                goto done;
     2744        }
     2745
     2746        enum_values = talloc_zero_array(tmp_ctx,
     2747                                        struct spoolss_PrinterEnumValues,
     2748                                        num_values);
     2749        if (enum_values == NULL){
     2750                result = WERR_NOMEM;
     2751                goto done;
     2752        }
     2753
     2754        for (i = 0; i < num_values; i++){
     2755                enum_values[i].value_name = enum_names[i];
     2756                enum_values[i].value_name_len = strlen_m_term(enum_names[i]) * 2;
     2757                enum_values[i].type = enum_types[i];
     2758                enum_values[i].data_length = enum_data_blobs[i].length;
     2759                enum_values[i].data = NULL;
     2760                if (enum_values[i].data_length != 0){
     2761                        enum_values[i].data = &enum_data_blobs[i];
     2762                }
     2763        }
     2764
    29532765        if (!W_ERROR_IS_OK(result)) {
    29542766                DEBUG(0, ("winreg_printer_enumforms1: Could not enumerate values in %s: %s\n",
     
    30012813
    30022814done:
    3003         if (winreg_handle != NULL) {
    3004                 WERROR ignore;
    3005 
    3006                 if (is_valid_policy_hnd(&key_hnd)) {
    3007                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    3008                 }
    3009                 if (is_valid_policy_hnd(&hive_hnd)) {
    3010                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    3011                 }
     2815        if (is_valid_policy_hnd(&key_hnd)) {
     2816                dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
     2817        }
     2818        if (is_valid_policy_hnd(&hive_hnd)) {
     2819                dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    30122820        }
    30132821
     
    30272835        uint32_t i;
    30282836        WERROR result = WERR_OK;
     2837        WERROR ignore;
    30292838        NTSTATUS status;
    30302839        TALLOC_CTX *tmp_ctx;
     
    30802889
    30812890done:
    3082         if (winreg_handle != NULL) {
    3083                 WERROR ignore;
    3084 
    3085                 if (is_valid_policy_hnd(&key_hnd)) {
    3086                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    3087                 }
    3088                 if (is_valid_policy_hnd(&hive_hnd)) {
    3089                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    3090                 }
     2891        if (is_valid_policy_hnd(&key_hnd)) {
     2892                dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
     2893        }
     2894        if (is_valid_policy_hnd(&hive_hnd)) {
     2895                dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    30912896        }
    30922897
     
    31012906{
    31022907        uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    3103         struct policy_handle hive_hnd, key_hnd;
     2908        struct policy_handle hive_hnd = { 0, };
     2909        struct policy_handle key_hnd = { 0, };
    31042910        struct winreg_String wvalue = { 0, };
    31052911        DATA_BLOB blob;
     
    32073013        uint32_t i;
    32083014        WERROR result;
     3015        WERROR ignore;
    32093016        NTSTATUS status;
    32103017        TALLOC_CTX *tmp_ctx;
     
    33093116        result = WERR_OK;
    33103117done:
    3311         if (winreg_handle != NULL) {
    3312                 WERROR ignore;
    3313 
    3314                 if (is_valid_policy_hnd(&key_hnd)) {
    3315                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    3316                 }
    3317                 if (is_valid_policy_hnd(&hive_hnd)) {
    3318                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    3319                 }
     3118        if (is_valid_policy_hnd(&key_hnd)) {
     3119                dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
     3120        }
     3121        if (is_valid_policy_hnd(&hive_hnd)) {
     3122                dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    33203123        }
    33213124
     
    36773480        TALLOC_CTX *tmp_ctx;
    36783481        WERROR result;
     3482        NTSTATUS status;
    36793483        uint32_t i;
     3484        const char **enum_names = NULL;
     3485        enum winreg_Type *enum_types = NULL;
     3486        DATA_BLOB *enum_data_blobs = NULL;
    36803487
    36813488        ZERO_STRUCT(hive_hnd);
     
    37273534        }
    37283535
    3729         result = winreg_printer_enumvalues(tmp_ctx,
    3730                                            winreg_handle,
    3731                                            &key_hnd,
    3732                                            &num_values,
    3733                                            &enum_values);
     3536        status = dcerpc_winreg_enumvals(tmp_ctx,
     3537                                        winreg_handle,
     3538                                        &key_hnd,
     3539                                        &num_values,
     3540                                        &enum_names,
     3541                                        &enum_types,
     3542                                        &enum_data_blobs,
     3543                                        &result);
     3544        if (!NT_STATUS_IS_OK(status)){
     3545                result = ntstatus_to_werror(status);
     3546        }
     3547
    37343548        if (!W_ERROR_IS_OK(result)) {
    37353549                DEBUG(0, ("winreg_get_driver: "
     
    37403554        }
    37413555
     3556        enum_values = talloc_zero_array(tmp_ctx,
     3557                                        struct spoolss_PrinterEnumValues,
     3558                                        num_values);
     3559        if (enum_values == NULL){
     3560                result = WERR_NOMEM;
     3561                goto done;
     3562        }
     3563
     3564        for (i = 0; i < num_values; i++){
     3565                enum_values[i].value_name = enum_names[i];
     3566                enum_values[i].value_name_len = strlen_m_term(enum_names[i]) * 2;
     3567                enum_values[i].type = enum_types[i];
     3568                enum_values[i].data_length = enum_data_blobs[i].length;
     3569                enum_values[i].data = NULL;
     3570                if (enum_values[i].data_length != 0){
     3571                        enum_values[i].data = &enum_data_blobs[i];
     3572                }
     3573        }
     3574
    37423575        info8 = talloc_zero(tmp_ctx, struct spoolss_DriverInfo8);
    37433576        if (info8 == NULL) {
     
    37693602                                                 "Version",
    37703603                                                 &tmp);
    3771                 if (NT_STATUS_IS_OK(result)) {
     3604                if (W_ERROR_IS_OK(result)) {
    37723605                        info8->version = (enum spoolss_DriverOSVersion) tmp;
    37733606                }
     
    39363769        char *key_name;
    39373770        WERROR result;
     3771        NTSTATUS status;
    39383772
    39393773        ZERO_STRUCT(hive_hnd);
     
    39833817        }
    39843818
    3985         result = winreg_printer_delete_subkeys(tmp_ctx,
    3986                                                winreg_handle,
    3987                                                &hive_hnd,
    3988                                                access_mask,
    3989                                                key_name);
     3819        status = dcerpc_winreg_delete_subkeys_recursive(tmp_ctx,
     3820                                                        winreg_handle,
     3821                                                        &hive_hnd,
     3822                                                        access_mask,
     3823                                                        key_name,
     3824                                                        &result);
     3825
     3826        if (!NT_STATUS_IS_OK(status)){
     3827                DEBUG(0, ("winreg_del_driver: "
     3828                          "Could not open driver (%s,%s,%u): %s\n",
     3829                          info8->driver_name, info8->architecture,
     3830                          version, nt_errstr(status)));
     3831                goto done;
     3832        }
     3833
    39903834        if (!W_ERROR_IS_OK(result)) {
    39913835                DEBUG(0, ("winreg_del_driver: "
  • vendor/current/source3/rpc_client/init_netlogon.c

    r740 r988  
    22 *  Unix SMB/CIFS implementation.
    33 *  RPC Pipe client / server routines
    4  *  Copyright (C) Guenther Deschner                  2008.
     4 *  Copyright (C) Guenther Deschner                  2008,2012
    55 *
    66 *  This program is free software; you can redistribute it and/or modify
     
    2020#include "includes.h"
    2121#include "../libcli/auth/libcli_auth.h"
    22 #include "../lib/crypto/arcfour.h"
     22#include "../lib/crypto/crypto.h"
    2323#include "rpc_client/init_netlogon.h"
    2424
     
    2828
    2929void init_netr_CryptPassword(const char *pwd,
    30                              unsigned char session_key[16],
     30                             struct netlogon_creds_CredentialState *creds,
    3131                             struct netr_CryptPassword *pwd_buf)
    3232{
     
    3535        encode_pw_buffer(password_buf.data, pwd, STR_UNICODE);
    3636
    37         arcfour_crypt(password_buf.data, session_key, 516);
     37        if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
     38                netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
     39        } else {
     40                netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
     41        }
    3842        memcpy(pwd_buf->data, password_buf.data, 512);
    3943        pwd_buf->length = IVAL(password_buf.data, 512);
  • vendor/current/source3/rpc_client/init_netlogon.h

    r740 r988  
    2424
    2525void init_netr_CryptPassword(const char *pwd,
    26                              unsigned char session_key[16],
     26                             struct netlogon_creds_CredentialState *creds,
    2727                             struct netr_CryptPassword *pwd_buf);
    2828
  • vendor/current/source3/rpc_client/init_spoolss.c

    r740 r988  
    108108        s->comment              = i->comment;
    109109        s->location             = i->location;
    110         s->devmode_ptr          = 0;
     110        s->devmode_ptr          = NULL;
    111111        s->sepfile              = i->sepfile;
    112112        s->printprocessor       = i->printprocessor;
    113113        s->datatype             = i->datatype;
    114114        s->parameters           = i->parameters;
    115         s->secdesc_ptr          = 0;
     115        s->secdesc_ptr          = NULL;
    116116        s->attributes           = i->attributes;
    117117        s->priority             = i->priority;
  • vendor/current/source3/rpc_client/rpc_client.h

    r919 r988  
    4545        char *srv_name_slash;
    4646
    47         uint16 max_xmit_frag;
    48         uint16 max_recv_frag;
     47        uint16_t max_xmit_frag;
     48        uint16_t max_recv_frag;
    4949
    5050        struct pipe_auth_data *auth;
    51 
    52         /* The following is only non-null on a netlogon client pipe. */
    53         struct netlogon_creds_CredentialState *dc;
    5451};
    5552
  • vendor/current/source3/rpc_client/rpc_transport.h

    r740 r988  
    3737         */
    3838        struct tevent_req *(*read_send)(TALLOC_CTX *mem_ctx,
    39                                         struct event_context *ev,
     39                                        struct tevent_context *ev,
    4040                                        uint8_t *data, size_t size,
    4141                                        void *priv);
     
    4949         */
    5050        struct tevent_req *(*write_send)(TALLOC_CTX *mem_ctx,
    51                                          struct event_context *ev,
     51                                         struct tevent_context *ev,
    5252                                         const uint8_t *data, size_t size,
    5353                                         void *priv);
     
    6464         */
    6565        struct tevent_req *(*trans_send)(TALLOC_CTX *mem_ctx,
    66                                          struct event_context *ev,
    67                                          uint8_t *data, size_t data_len,
     66                                         struct tevent_context *ev,
     67                                         const uint8_t *data, size_t data_len,
    6868                                         uint32_t max_rdata_len,
    6969                                         void *priv);
     
    8383struct cli_state;
    8484struct tevent_req *rpc_transport_np_init_send(TALLOC_CTX *mem_ctx,
    85                                               struct event_context *ev,
     85                                              struct tevent_context *ev,
    8686                                              struct cli_state *cli,
    87                                               const struct ndr_syntax_id *abstract_syntax);
     87                                              const struct ndr_interface_table *table);
    8888NTSTATUS rpc_transport_np_init_recv(struct tevent_req *req,
    8989                                    TALLOC_CTX *mem_ctx,
    9090                                    struct rpc_cli_transport **presult);
    9191NTSTATUS rpc_transport_np_init(TALLOC_CTX *mem_ctx, struct cli_state *cli,
    92                                const struct ndr_syntax_id *abstract_syntax,
     92                               const struct ndr_interface_table *table,
    9393                               struct rpc_cli_transport **presult);
    9494
     
    103103                                struct tstream_context **stream,
    104104                                struct rpc_cli_transport **presult);
    105 struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p);
    106105
    107106#endif /* _RPC_CLIENT_RPC_TRANSPORT_H_ */
  • vendor/current/source3/rpc_client/rpc_transport_np.c

    r740 r988  
    2121#include "../lib/util/tevent_ntstatus.h"
    2222#include "rpc_client/rpc_transport.h"
    23 #include "libsmb/cli_np_tstream.h"
     23#include "librpc/ndr/ndr_table.h"
     24#include "libcli/smb/smbXcli_base.h"
     25#include "libcli/smb/tstream_smbXcli_np.h"
     26#include "client.h"
    2427
    2528#undef DBGC_CLASS
     
    2831struct rpc_transport_np_init_state {
    2932        struct rpc_cli_transport *transport;
     33        int retries;
     34        struct tevent_context *ev;
     35        struct smbXcli_conn *conn;
     36        int timeout;
     37        struct timeval abs_timeout;
     38        const char *pipe_name;
     39        struct smbXcli_session *session;
     40        struct smbXcli_tcon *tcon;
     41        uint16_t pid;
    3042};
    3143
     
    3345
    3446struct tevent_req *rpc_transport_np_init_send(TALLOC_CTX *mem_ctx,
    35                                               struct event_context *ev,
     47                                              struct tevent_context *ev,
    3648                                              struct cli_state *cli,
    37                                               const struct ndr_syntax_id *abstract_syntax)
     49                                              const struct ndr_interface_table *table)
    3850{
    3951        struct tevent_req *req;
    4052        struct rpc_transport_np_init_state *state;
    41         const char *pipe_name;
    4253        struct tevent_req *subreq;
    4354
     
    4859        }
    4960
    50         pipe_name = get_pipe_name_from_syntax(state, abstract_syntax);
    51         if (tevent_req_nomem(pipe_name, req)) {
     61        if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
     62                state->tcon = cli->smb2.tcon;
     63                state->session = cli->smb2.session;
     64        } else {
     65                state->tcon = cli->smb1.tcon;
     66                state->session = cli->smb1.session;
     67                state->pid = cli->smb1.pid;
     68        }
     69
     70        state->ev = ev;
     71        state->conn = cli->conn;
     72        state->timeout = cli->timeout;
     73        state->abs_timeout = timeval_current_ofs_msec(cli->timeout);
     74        state->pipe_name = dcerpc_default_transport_endpoint(state, NCACN_NP,
     75                                                             table);
     76        if (tevent_req_nomem(state->pipe_name, req)) {
    5277                return tevent_req_post(req, ev);
    5378        }
    5479
    55         subreq = tstream_cli_np_open_send(state, ev, cli, pipe_name);
     80        while (state->pipe_name[0] == '\\') {
     81                state->pipe_name++;
     82        }
     83
     84        subreq = tstream_smbXcli_np_open_send(state, ev, state->conn,
     85                                              state->session, state->tcon,
     86                                              state->pid, state->timeout,
     87                                              state->pipe_name);
    5688        if (tevent_req_nomem(subreq, req)) {
    5789                return tevent_req_post(req, ev);
     
    6092
    6193        return req;
     94}
     95
     96static void rpc_transport_np_init_pipe_open_retry(struct tevent_context *ev,
     97                                                  struct tevent_timer *te,
     98                                                  struct timeval t,
     99                                                  void *priv_data)
     100{
     101        struct tevent_req *subreq;
     102        struct tevent_req *req = talloc_get_type(priv_data, struct tevent_req);
     103        struct rpc_transport_np_init_state *state = tevent_req_data(
     104                req, struct rpc_transport_np_init_state);
     105
     106        subreq = tstream_smbXcli_np_open_send(state, ev,
     107                                              state->conn,
     108                                              state->session,
     109                                              state->tcon,
     110                                              state->pid,
     111                                              state->timeout,
     112                                              state->pipe_name);
     113        if (tevent_req_nomem(subreq, req)) {
     114                return;
     115        }
     116        tevent_req_set_callback(subreq, rpc_transport_np_init_pipe_open, req);
     117        state->retries++;
    62118}
    63119
     
    71127        struct tstream_context *stream;
    72128
    73         status = tstream_cli_np_open_recv(subreq, state, &stream);
     129        status = tstream_smbXcli_np_open_recv(subreq, state, &stream);
    74130        TALLOC_FREE(subreq);
    75         if (!NT_STATUS_IS_OK(status)) {
     131        if (NT_STATUS_EQUAL(status, NT_STATUS_PIPE_NOT_AVAILABLE)
     132                                && (!timeval_expired(&state->abs_timeout))) {
     133                struct tevent_timer *te;
     134                /*
     135                 * Retry on STATUS_PIPE_NOT_AVAILABLE, Windows starts some
     136                 * servers (FssagentRpc) on demand.
     137                 */
     138                DEBUG(2, ("RPC pipe %s not available, retry %d\n",
     139                          state->pipe_name, state->retries));
     140                te = tevent_add_timer(state->ev, state,
     141                                 timeval_current_ofs_msec(100 * state->retries),
     142                                 rpc_transport_np_init_pipe_open_retry, req);
     143                if (tevent_req_nomem(te, req)) {
     144                        DEBUG(2, ("Failed to create asynchronous "
     145                                        "tevent_timer"));
     146                }
     147                return;
     148        } else if (!NT_STATUS_IS_OK(status)) {
    76149                tevent_req_nterror(req, status);
    77150                return;
     
    106179
    107180NTSTATUS rpc_transport_np_init(TALLOC_CTX *mem_ctx, struct cli_state *cli,
    108                                const struct ndr_syntax_id *abstract_syntax,
     181                               const struct ndr_interface_table *table,
    109182                               struct rpc_cli_transport **presult)
    110183{
    111184        TALLOC_CTX *frame = talloc_stackframe();
    112         struct event_context *ev;
     185        struct tevent_context *ev;
    113186        struct tevent_req *req;
    114187        NTSTATUS status = NT_STATUS_OK;
    115188
    116         ev = event_context_init(frame);
     189        ev = samba_tevent_context_init(frame);
    117190        if (ev == NULL) {
    118191                status = NT_STATUS_NO_MEMORY;
     
    120193        }
    121194
    122         req = rpc_transport_np_init_send(frame, ev, cli, abstract_syntax);
     195        req = rpc_transport_np_init_send(frame, ev, cli, table);
    123196        if (req == NULL) {
    124197                status = NT_STATUS_NO_MEMORY;
     
    126199        }
    127200
    128         if (!tevent_req_poll(req, ev)) {
    129                 status = map_nt_error_from_unix(errno);
     201        if (!tevent_req_poll_ntstatus(req, ev, &status)) {
    130202                goto fail;
    131203        }
  • vendor/current/source3/rpc_client/rpc_transport_tstream.c

    r740 r988  
    2222#include "rpc_client/rpc_transport.h"
    2323#include "lib/tsocket/tsocket.h"
    24 #include "libsmb/cli_np_tstream.h"
     24#include "libcli/smb/tstream_smbXcli_np.h"
    2525#include "cli_pipe.h"
    2626
     
    5050        }
    5151
    52         if (!tstream_is_cli_np(transp->stream)) {
     52        if (!tstream_is_smbXcli_np(transp->stream)) {
    5353                return true;
    5454        }
     
    7474        }
    7575
    76         if (tstream_is_cli_np(transp->stream)) {
     76        if (tstream_is_smbXcli_np(transp->stream)) {
    7777                transp->timeout = timeout;
    78                 return tstream_cli_np_set_timeout(transp->stream, timeout);
     78                return tstream_smbXcli_np_set_timeout(transp->stream, timeout);
    7979        }
    8080
     
    172172
    173173static struct tevent_req *rpc_tstream_read_send(TALLOC_CTX *mem_ctx,
    174                                              struct event_context *ev,
     174                                             struct tevent_context *ev,
    175175                                             uint8_t *data, size_t size,
    176176                                             void *priv)
     
    187187        }
    188188        if (!rpc_tstream_is_connected(transp)) {
    189                 tevent_req_nterror(req, NT_STATUS_CONNECTION_INVALID);
     189                NTSTATUS status = NT_STATUS_CONNECTION_DISCONNECTED;
     190                if (tstream_is_smbXcli_np(transp->stream)) {
     191                        status = NT_STATUS_PIPE_DISCONNECTED;
     192                }
     193                tevent_req_nterror(req, status);
    190194                return tevent_req_post(req, ev);
    191195        }
     
    203207        }
    204208
    205         endtime = timeval_current_ofs(0, transp->timeout * 1000);
     209        endtime = timeval_current_ofs_msec(transp->timeout);
    206210        if (!tevent_req_set_endtime(subreq, ev, endtime)) {
    207211                goto fail;
     
    247251
    248252struct rpc_tstream_write_state {
    249         struct event_context *ev;
     253        struct tevent_context *ev;
    250254        struct rpc_tstream_state *transp;
    251255        struct iovec iov;
     
    256260
    257261static struct tevent_req *rpc_tstream_write_send(TALLOC_CTX *mem_ctx,
    258                                               struct event_context *ev,
     262                                              struct tevent_context *ev,
    259263                                              const uint8_t *data, size_t size,
    260264                                              void *priv)
     
    271275        }
    272276        if (!rpc_tstream_is_connected(transp)) {
    273                 tevent_req_nterror(req, NT_STATUS_CONNECTION_INVALID);
     277                NTSTATUS status = NT_STATUS_CONNECTION_DISCONNECTED;
     278                if (tstream_is_smbXcli_np(transp->stream)) {
     279                        status = NT_STATUS_PIPE_DISCONNECTED;
     280                }
     281                tevent_req_nterror(req, status);
    274282                return tevent_req_post(req, ev);
    275283        }
     
    287295        }
    288296
    289         endtime = timeval_current_ofs(0, transp->timeout * 1000);
     297        endtime = timeval_current_ofs_msec(transp->timeout);
    290298        if (!tevent_req_set_endtime(subreq, ev, endtime)) {
    291299                goto fail;
     
    349357static struct tevent_req *rpc_tstream_trans_send(TALLOC_CTX *mem_ctx,
    350358                                                 struct tevent_context *ev,
    351                                                  uint8_t *data, size_t data_len,
     359                                                 const uint8_t *data, size_t data_len,
    352360                                                 uint32_t max_rdata_len,
    353361                                                 void *priv)
     
    358366        struct rpc_tstream_trans_state *state;
    359367        struct timeval endtime;
     368        bool use_trans = false;
    360369
    361370        req = tevent_req_create(mem_ctx, &state,
     
    366375
    367376        if (!rpc_tstream_is_connected(transp)) {
    368                 tevent_req_nterror(req, NT_STATUS_CONNECTION_INVALID);
     377                NTSTATUS status = NT_STATUS_CONNECTION_DISCONNECTED;
     378                if (tstream_is_smbXcli_np(transp->stream)) {
     379                        status = NT_STATUS_PIPE_DISCONNECTED;
     380                }
     381                tevent_req_nterror(req, status);
    369382                return tevent_req_post(req, ev);
    370383        }
     
    375388        state->max_rdata_len = max_rdata_len;
    376389
    377         endtime = timeval_current_ofs(0, transp->timeout * 1000);
     390        endtime = timeval_current_ofs_msec(transp->timeout);
     391
     392        if (tstream_is_smbXcli_np(transp->stream)) {
     393                use_trans = true;
     394        }
     395        if (tevent_queue_length(transp->write_queue) > 0) {
     396                use_trans = false;
     397        }
     398        if (tevent_queue_length(transp->read_queue) > 0) {
     399                use_trans = false;
     400        }
     401
     402        if (use_trans) {
     403                tstream_smbXcli_np_use_trans(transp->stream);
     404        }
    378405
    379406        subreq = tstream_writev_queue_send(state, ev,
     
    388415        }
    389416        tevent_req_set_callback(subreq, rpc_tstream_trans_writev, req);
    390 
    391         if (tstream_is_cli_np(transp->stream)) {
    392                 tstream_cli_np_use_trans(transp->stream);
    393         }
    394417
    395418        subreq = tstream_readv_pdu_queue_send(state, ev,
     
    546569        state->timeout = 10000; /* 10 seconds. */
    547570
    548         if (tstream_is_cli_np(state->stream)) {
     571        if (tstream_is_smbXcli_np(state->stream)) {
    549572                result->trans_send = rpc_tstream_trans_send;
    550573                result->trans_recv = rpc_tstream_trans_recv;
     
    563586        return NT_STATUS_OK;
    564587}
    565 
    566 struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p)
    567 {
    568         struct rpc_tstream_state *transp =
    569                 talloc_get_type_abort(p->transport->priv,
    570                 struct rpc_tstream_state);
    571         bool ok;
    572 
    573         ok = rpccli_is_connected(p);
    574         if (!ok) {
    575                 return NULL;
    576         }
    577 
    578         if (!tstream_is_cli_np(transp->stream)) {
    579                 return NULL;
    580         }
    581 
    582         return tstream_cli_np_get_cli_state(transp->stream);
    583 }
  • vendor/current/source3/rpc_client/util_netlogon.c

    r740 r988  
    5353
    5454        COPY_LSA_STRING(mem_ctx, in, out, logon_server);
    55         COPY_LSA_STRING(mem_ctx, in, out, domain);
     55        COPY_LSA_STRING(mem_ctx, in, out, logon_domain);
    5656
    5757        if (in->domain_sid) {
Note: See TracChangeset for help on using the changeset viewer.