rpc_client/cli_pipe.c

ソースコードを見る。

関数

static int map_pipe_auth_type_to_rpc_auth_type (enum pipe_auth_type auth_type)
static uint32 get_rpc_call_id (void)
static NTSTATUS rpc_read (struct rpc_pipe_client *cli, prs_struct *current_pdu, uint32 data_to_read, uint32 *current_pdu_offset)
static NTSTATUS cli_pipe_get_current_pdu (struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
static NTSTATUS cli_pipe_verify_ntlmssp (struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu, uint8 *p_ss_padding_len)
static NTSTATUS cli_pipe_verify_schannel (struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu, uint8 *p_ss_padding_len)
static NTSTATUS cli_pipe_validate_rpc_response (struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu, uint8 *p_ss_padding_len)
static NTSTATUS cli_pipe_validate_current_pdu (struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu, uint8 expected_pkt_type, char **ppdata, uint32 *pdata_len, prs_struct *return_data)
static NTSTATUS cli_pipe_reset_current_pdu (struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
static NTSTATUS rpc_api_pipe (struct rpc_pipe_client *cli, prs_struct *data, prs_struct *rbuf, uint8 expected_pkt_type)
static NTSTATUS create_krb5_auth_bind_req (struct rpc_pipe_client *cli, enum pipe_auth_level auth_level, RPC_HDR_AUTH *pauth_out, prs_struct *auth_data)
static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req (struct rpc_pipe_client *cli, enum pipe_auth_level auth_level, RPC_HDR_AUTH *pauth_out, prs_struct *auth_data)
static NTSTATUS create_ntlmssp_auth_rpc_bind_req (struct rpc_pipe_client *cli, enum pipe_auth_level auth_level, RPC_HDR_AUTH *pauth_out, prs_struct *auth_data)
static NTSTATUS create_schannel_auth_rpc_bind_req (struct rpc_pipe_client *cli, enum pipe_auth_level auth_level, RPC_HDR_AUTH *pauth_out, prs_struct *auth_data)
static NTSTATUS create_bind_or_alt_ctx_internal (enum RPC_PKT_TYPE pkt_type, prs_struct *rpc_out, uint32 rpc_call_id, RPC_IFACE *abstract, RPC_IFACE *transfer, RPC_HDR_AUTH *phdr_auth, prs_struct *pauth_info)
static NTSTATUS create_rpc_bind_req (struct rpc_pipe_client *cli, prs_struct *rpc_out, uint32 rpc_call_id, RPC_IFACE *abstract, RPC_IFACE *transfer, enum pipe_auth_type auth_type, enum pipe_auth_level auth_level)
static NTSTATUS add_ntlmssp_auth_footer (struct rpc_pipe_client *cli, RPC_HDR *phdr, uint32 ss_padding_len, prs_struct *outgoing_pdu)
static NTSTATUS add_schannel_auth_footer (struct rpc_pipe_client *cli, RPC_HDR *phdr, uint32 ss_padding_len, prs_struct *outgoing_pdu)
static uint32 calculate_data_len_tosend (struct rpc_pipe_client *cli, uint32 data_left, uint16 *p_frag_len, uint16 *p_auth_len, uint32 *p_ss_padding)
NTSTATUS rpc_api_pipe_req (struct rpc_pipe_client *cli, uint8 op_num, prs_struct *in_data, prs_struct *out_data)
static BOOL rpc_pipe_set_hnd_state (struct rpc_pipe_client *cli, const char *pipe_name, uint16 device_state)
static BOOL valid_pipe_name (const int pipe_idx, RPC_IFACE *abstract, RPC_IFACE *transfer)
static BOOL check_bind_response (RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFACE *transfer)
static NTSTATUS create_rpc_bind_auth3 (struct rpc_pipe_client *cli, uint32 rpc_call_id, enum pipe_auth_type auth_type, enum pipe_auth_level auth_level, DATA_BLOB *pauth_blob, prs_struct *rpc_out)
static NTSTATUS rpc_finish_auth3_bind (struct rpc_pipe_client *cli, RPC_HDR *phdr, prs_struct *rbuf, uint32 rpc_call_id, enum pipe_auth_type auth_type, enum pipe_auth_level auth_level)
static NTSTATUS create_rpc_alter_context (uint32 rpc_call_id, RPC_IFACE *abstract, RPC_IFACE *transfer, enum pipe_auth_level auth_level, const DATA_BLOB *pauth_blob, prs_struct *rpc_out)
static NTSTATUS rpc_finish_spnego_ntlmssp_bind (struct rpc_pipe_client *cli, RPC_HDR *phdr, prs_struct *rbuf, uint32 rpc_call_id, RPC_IFACE *abstract, RPC_IFACE *transfer, enum pipe_auth_type auth_type, enum pipe_auth_level auth_level)
static NTSTATUS rpc_pipe_bind (struct rpc_pipe_client *cli, enum pipe_auth_type auth_type, enum pipe_auth_level auth_level)
static struct rpc_pipe_clientcli_rpc_pipe_open (struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
rpc_pipe_clientcli_rpc_pipe_open_noauth (struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
static void cli_ntlmssp_auth_free (struct cli_pipe_auth_data *auth)
static struct rpc_pipe_clientcli_rpc_pipe_open_ntlmssp_internal (struct cli_state *cli, int pipe_idx, enum pipe_auth_type auth_type, enum pipe_auth_level auth_level, const char *domain, const char *username, const char *password, NTSTATUS *perr)
rpc_pipe_clientcli_rpc_pipe_open_ntlmssp (struct cli_state *cli, int pipe_idx, enum pipe_auth_level auth_level, const char *domain, const char *username, const char *password, NTSTATUS *perr)
rpc_pipe_clientcli_rpc_pipe_open_spnego_ntlmssp (struct cli_state *cli, int pipe_idx, enum pipe_auth_level auth_level, const char *domain, const char *username, const char *password, NTSTATUS *perr)
static BOOL get_schannel_session_key_common (struct rpc_pipe_client *netlogon_pipe, struct cli_state *cli, const char *domain, uint32 *pneg_flags, NTSTATUS *perr)
rpc_pipe_clientget_schannel_session_key (struct cli_state *cli, const char *domain, uint32 *pneg_flags, NTSTATUS *perr)
rpc_pipe_clientcli_rpc_pipe_open_schannel_with_key (struct cli_state *cli, int pipe_idx, enum pipe_auth_level auth_level, const char *domain, const struct dcinfo *pdc, NTSTATUS *perr)
static struct rpc_pipe_clientget_schannel_session_key_auth_ntlmssp (struct cli_state *cli, const char *domain, const char *username, const char *password, uint32 *pneg_flags, NTSTATUS *perr)
rpc_pipe_clientcli_rpc_pipe_open_ntlmssp_auth_schannel (struct cli_state *cli, int pipe_idx, enum pipe_auth_level auth_level, const char *domain, const char *username, const char *password, NTSTATUS *perr)
rpc_pipe_clientcli_rpc_pipe_open_schannel (struct cli_state *cli, int pipe_idx, enum pipe_auth_level auth_level, const char *domain, NTSTATUS *perr)
static void kerberos_auth_struct_free (struct cli_pipe_auth_data *a)
rpc_pipe_clientcli_rpc_pipe_open_krb5 (struct cli_state *cli, int pipe_idx, enum pipe_auth_level auth_level, const char *service_princ, const char *username, const char *password, NTSTATUS *perr)
void cli_rpc_pipe_close (struct rpc_pipe_client *cli)

変数

pipe_id_info pipe_names []


関数

static int map_pipe_auth_type_to_rpc_auth_type ( enum pipe_auth_type  auth_type  )  [static]

cli_pipe.c32 行で定義されています。

参照先 PIPE_AUTH_TYPE_KRB5PIPE_AUTH_TYPE_NONEPIPE_AUTH_TYPE_NTLMSSPPIPE_AUTH_TYPE_SCHANNELPIPE_AUTH_TYPE_SPNEGO_KRB5PIPE_AUTH_TYPE_SPNEGO_NTLMSSP.

参照元 add_ntlmssp_auth_footer()add_schannel_auth_footer()create_rpc_bind_auth3().

00033 {
00034         switch (auth_type) {
00035 
00036         case PIPE_AUTH_TYPE_NONE:
00037                 return RPC_ANONYMOUS_AUTH_TYPE;
00038 
00039         case PIPE_AUTH_TYPE_NTLMSSP:
00040                 return RPC_NTLMSSP_AUTH_TYPE;
00041 
00042         case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
00043         case PIPE_AUTH_TYPE_SPNEGO_KRB5:
00044                 return RPC_SPNEGO_AUTH_TYPE;
00045 
00046         case PIPE_AUTH_TYPE_SCHANNEL:
00047                 return RPC_SCHANNEL_AUTH_TYPE;
00048 
00049         case PIPE_AUTH_TYPE_KRB5:
00050                 return RPC_KRB5_AUTH_TYPE;
00051 
00052         default:
00053                 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
00054                         "auth type %u\n",
00055                         (unsigned int)auth_type ));
00056                 break;
00057         }
00058         return -1;
00059 }

static uint32 get_rpc_call_id ( void   )  [static]

cli_pipe.c65 行で定義されています。

参照元 rpc_api_pipe_req()rpc_pipe_bind().

00066 {
00067         static uint32 call_id = 0;
00068         return ++call_id;
00069 }

static NTSTATUS rpc_read ( struct rpc_pipe_client cli,
prs_struct current_pdu,
uint32  data_to_read,
uint32 *  current_pdu_offset 
) [static]

cli_pipe.c76 行で定義されています。

参照先 clicli_dos_error()cli_errstr()cli_get_nt_error()cli_is_dos_error()cli_is_nt_error()cli_nt_error()cli_read()dos_to_ntstatus()nt_errstr()size.

参照元 cli_pipe_get_current_pdu().

00080 {
00081         size_t size = (size_t)cli->max_recv_frag;
00082         uint32 stream_offset = 0;
00083         ssize_t num_read;
00084         char *pdata;
00085         ssize_t extra_data_size = ((ssize_t)*current_pdu_offset) + ((ssize_t)data_to_read) - (ssize_t)prs_data_size(current_pdu);
00086 
00087         DEBUG(5,("rpc_read: data_to_read: %u current_pdu offset: %u extra_data_size: %d\n",
00088                 (unsigned int)data_to_read, (unsigned int)*current_pdu_offset, (int)extra_data_size ));
00089 
00090         /*
00091          * Grow the buffer if needed to accommodate the data to be read.
00092          */
00093 
00094         if (extra_data_size > 0) {
00095                 if(!prs_force_grow(current_pdu, (uint32)extra_data_size)) {
00096                         DEBUG(0,("rpc_read: Failed to grow parse struct by %d bytes.\n", (int)extra_data_size ));
00097                         return NT_STATUS_NO_MEMORY;
00098                 }
00099                 DEBUG(5,("rpc_read: grew buffer by %d bytes to %u\n", (int)extra_data_size, prs_data_size(current_pdu) ));
00100         }
00101 
00102         pdata = prs_data_p(current_pdu) + *current_pdu_offset;
00103 
00104         do {
00105                 /* read data using SMBreadX */
00106                 if (size > (size_t)data_to_read) {
00107                         size = (size_t)data_to_read;
00108                 }
00109 
00110                 num_read = cli_read(cli->cli, cli->fnum, pdata,
00111                                          (off_t)stream_offset, size);
00112 
00113                 DEBUG(5,("rpc_read: num_read = %d, read offset: %u, to read: %u\n",
00114                         (int)num_read, (unsigned int)stream_offset, (unsigned int)data_to_read));
00115 
00116                 /*
00117                  * A dos error of ERRDOS/ERRmoredata is not an error.
00118                  */
00119                 if (cli_is_dos_error(cli->cli)) {
00120                         uint32 ecode;
00121                         uint8 eclass;
00122                         cli_dos_error(cli->cli, &eclass, &ecode);
00123                         if (eclass != ERRDOS && ecode != ERRmoredata) {
00124                                 DEBUG(0,("rpc_read: DOS Error %d/%u (%s) in cli_read on pipe %s\n",
00125                                         eclass, (unsigned int)ecode,
00126                                         cli_errstr(cli->cli),
00127                                         cli->pipe_name ));
00128                                 return dos_to_ntstatus(eclass, ecode);
00129                         }
00130                 }
00131 
00132                 /*
00133                  * Likewise for NT_STATUS_BUFFER_TOO_SMALL
00134                  */
00135                 if (cli_is_nt_error(cli->cli)) {
00136                         if (!NT_STATUS_EQUAL(cli_nt_error(cli->cli), NT_STATUS_BUFFER_TOO_SMALL)) {
00137                                 DEBUG(0,("rpc_read: Error (%s) in cli_read on pipe %s\n",
00138                                         nt_errstr(cli_nt_error(cli->cli)),
00139                                         cli->pipe_name ));
00140                                 return cli_nt_error(cli->cli);
00141                         }
00142                 }
00143 
00144                 if (num_read == -1) {
00145                         DEBUG(0,("rpc_read: Error - cli_read on pipe %s returned -1\n",
00146                                 cli->pipe_name ));
00147                         return cli_get_nt_error(cli->cli);
00148                 }
00149 
00150                 data_to_read -= num_read;
00151                 stream_offset += num_read;
00152                 pdata += num_read;
00153 
00154         } while (num_read > 0 && data_to_read > 0);
00155         /* && err == (0x80000000 | STATUS_BUFFER_OVERFLOW)); */
00156 
00157         /*
00158          * Update the current offset into current_pdu by the amount read.
00159          */
00160         *current_pdu_offset += stream_offset;
00161         return NT_STATUS_OK;
00162 }

static NTSTATUS cli_pipe_get_current_pdu ( struct rpc_pipe_client cli,
RPC_HDR prhdr,
prs_struct current_pdu 
) [static]

cli_pipe.c169 行で定義されています。

参照先 clirpc_hdr_info::frag_lenrpc_read()smb_io_rpc_hdr().

参照元 rpc_api_pipe().

00170 {
00171         NTSTATUS ret = NT_STATUS_OK;
00172         uint32 current_pdu_len = prs_data_size(current_pdu);
00173 
00174         /* Ensure we have at least RPC_HEADER_LEN worth of data to parse. */
00175         if (current_pdu_len < RPC_HEADER_LEN) {
00176                 /* rpc_read expands the current_pdu struct as neccessary. */
00177                 ret = rpc_read(cli, current_pdu, RPC_HEADER_LEN - current_pdu_len, &current_pdu_len);
00178                 if (!NT_STATUS_IS_OK(ret)) {
00179                         return ret;
00180                 }
00181         }
00182 
00183         /* This next call sets the endian bit correctly in current_pdu. */
00184         /* We will propagate this to rbuf later. */
00185         if(!smb_io_rpc_hdr("rpc_hdr   ", prhdr, current_pdu, 0)) {
00186                 DEBUG(0,("cli_pipe_get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
00187                 return NT_STATUS_BUFFER_TOO_SMALL;
00188         }
00189 
00190         /* Ensure we have frag_len bytes of data. */
00191         if (current_pdu_len < prhdr->frag_len) {
00192                 /* rpc_read expands the current_pdu struct as neccessary. */
00193                 ret = rpc_read(cli, current_pdu, (uint32)prhdr->frag_len - current_pdu_len, &current_pdu_len);
00194                 if (!NT_STATUS_IS_OK(ret)) {
00195                         return ret;
00196                 }
00197         }
00198 
00199         if (current_pdu_len < prhdr->frag_len) {
00200                 return NT_STATUS_BUFFER_TOO_SMALL;
00201         }
00202 
00203         return NT_STATUS_OK;
00204 }

static NTSTATUS cli_pipe_verify_ntlmssp ( struct rpc_pipe_client cli,
RPC_HDR prhdr,
prs_struct current_pdu,
uint8 *  p_ss_padding_len 
) [static]

cli_pipe.c212 行で定義されています。

参照先 rpc_hdr_info::auth_lenrpc_hdr_auth_info::auth_pad_lenclidata_blob_::datacli_state::desthostrpc_hdr_info::frag_lendata_blob_::lengthnt_errstr()ntlmssp_check_packet()ntlmssp_unseal_packet()PIPE_AUTH_LEVEL_CONNECTPIPE_AUTH_LEVEL_INTEGRITYPIPE_AUTH_LEVEL_NONEPIPE_AUTH_LEVEL_PRIVACYsmb_io_rpc_hdr_auth()status.

参照元 cli_pipe_validate_rpc_response().

00215 {
00216         RPC_HDR_AUTH auth_info;
00217         uint32 save_offset = prs_offset(current_pdu);
00218         uint32 auth_len = prhdr->auth_len;
00219         NTLMSSP_STATE *ntlmssp_state = cli->auth.a_u.ntlmssp_state;
00220         unsigned char *data = NULL;
00221         size_t data_len;
00222         unsigned char *full_packet_data = NULL;
00223         size_t full_packet_data_len;
00224         DATA_BLOB auth_blob;
00225         NTSTATUS status;
00226 
00227         if (cli->auth.auth_level == PIPE_AUTH_LEVEL_NONE || cli->auth.auth_level == PIPE_AUTH_LEVEL_CONNECT) {
00228                 return NT_STATUS_OK;
00229         }
00230 
00231         if (!ntlmssp_state) {
00232                 return NT_STATUS_INVALID_PARAMETER;
00233         }
00234 
00235         /* Ensure there's enough data for an authenticated response. */
00236         if ((auth_len > RPC_MAX_SIGN_SIZE) ||
00237                         (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
00238                 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
00239                         (unsigned int)auth_len ));
00240                 return NT_STATUS_BUFFER_TOO_SMALL;
00241         }
00242 
00243         /*
00244          * We need the full packet data + length (minus auth stuff) as well as the packet data + length
00245          * after the RPC header.
00246          * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
00247          * functions as NTLMv2 checks the rpc headers also.
00248          */
00249 
00250         data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
00251         data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
00252 
00253         full_packet_data = (unsigned char *)prs_data_p(current_pdu);
00254         full_packet_data_len = prhdr->frag_len - auth_len;
00255 
00256         /* Pull the auth header and the following data into a blob. */
00257         if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
00258                 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
00259                         (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
00260                 return NT_STATUS_BUFFER_TOO_SMALL;
00261         }
00262 
00263         if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
00264                 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
00265                 return NT_STATUS_BUFFER_TOO_SMALL;
00266         }
00267 
00268         auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
00269         auth_blob.length = auth_len;
00270 
00271         switch (cli->auth.auth_level) {
00272                 case PIPE_AUTH_LEVEL_PRIVACY:
00273                         /* Data is encrypted. */
00274                         status = ntlmssp_unseal_packet(ntlmssp_state,
00275                                                         data, data_len,
00276                                                         full_packet_data,
00277                                                         full_packet_data_len,
00278                                                         &auth_blob);
00279                         if (!NT_STATUS_IS_OK(status)) {
00280                                 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
00281                                         "packet from remote machine %s on pipe %s "
00282                                         "fnum 0x%x. Error was %s.\n",
00283                                         cli->cli->desthost,
00284                                         cli->pipe_name,
00285                                         (unsigned int)cli->fnum,
00286                                         nt_errstr(status) ));
00287                                 return status;
00288                         }
00289                         break;
00290                 case PIPE_AUTH_LEVEL_INTEGRITY:
00291                         /* Data is signed. */
00292                         status = ntlmssp_check_packet(ntlmssp_state,
00293                                                         data, data_len,
00294                                                         full_packet_data,
00295                                                         full_packet_data_len,
00296                                                         &auth_blob);
00297                         if (!NT_STATUS_IS_OK(status)) {
00298                                 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
00299                                         "packet from remote machine %s on pipe %s "
00300                                         "fnum 0x%x. Error was %s.\n",
00301                                         cli->cli->desthost,
00302                                         cli->pipe_name,
00303                                         (unsigned int)cli->fnum,
00304                                         nt_errstr(status) ));
00305                                 return status;
00306                         }
00307                         break;
00308                 default:
00309                         DEBUG(0,("cli_pipe_verify_ntlmssp: unknown internal auth level %d\n",
00310                                 cli->auth.auth_level ));
00311                         return NT_STATUS_INVALID_INFO_CLASS;
00312         }
00313 
00314         /*
00315          * Return the current pointer to the data offset.
00316          */
00317 
00318         if(!prs_set_offset(current_pdu, save_offset)) {
00319                 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
00320                         (unsigned int)save_offset ));
00321                 return NT_STATUS_BUFFER_TOO_SMALL;
00322         }
00323 
00324         /*
00325          * Remember the padding length. We must remove it from the real data
00326          * stream once the sign/seal is done.
00327          */
00328 
00329         *p_ss_padding_len = auth_info.auth_pad_len;
00330 
00331         return NT_STATUS_OK;
00332 }

static NTSTATUS cli_pipe_verify_schannel ( struct rpc_pipe_client cli,
RPC_HDR prhdr,
prs_struct current_pdu,
uint8 *  p_ss_padding_len 
) [static]

cli_pipe.c338 行で定義されています。

参照先 rpc_hdr_info::auth_lenrpc_hdr_auth_info::auth_pad_lenrpc_hdr_auth_info::auth_typeclicli_state::desthostrpc_hdr_info::frag_lenPIPE_AUTH_LEVEL_CONNECTPIPE_AUTH_LEVEL_NONESENDER_IS_ACCEPTORschannel_auth_struct::seq_numsmb_io_rpc_auth_schannel_chk()smb_io_rpc_hdr_auth().

参照元 cli_pipe_validate_rpc_response().

00341 {
00342         RPC_HDR_AUTH auth_info;
00343         RPC_AUTH_SCHANNEL_CHK schannel_chk;
00344         uint32 auth_len = prhdr->auth_len;
00345         uint32 save_offset = prs_offset(current_pdu);
00346         struct schannel_auth_struct *schannel_auth = cli->auth.a_u.schannel_auth;
00347         uint32 data_len;
00348 
00349         if (cli->auth.auth_level == PIPE_AUTH_LEVEL_NONE || cli->auth.auth_level == PIPE_AUTH_LEVEL_CONNECT) {
00350                 return NT_STATUS_OK;
00351         }
00352 
00353         if (auth_len != RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
00354                 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
00355                 return NT_STATUS_INVALID_PARAMETER;
00356         }
00357 
00358         if (!schannel_auth) {
00359                 return NT_STATUS_INVALID_PARAMETER;
00360         }
00361 
00362         /* Ensure there's enough data for an authenticated response. */
00363         if ((auth_len > RPC_MAX_SIGN_SIZE) ||
00364                         (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
00365                 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
00366                         (unsigned int)auth_len ));
00367                 return NT_STATUS_INVALID_PARAMETER;
00368         }
00369 
00370         data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
00371 
00372         if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
00373                 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
00374                         (unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));
00375                 return NT_STATUS_BUFFER_TOO_SMALL;
00376         }
00377                                                                                                                              
00378         if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
00379                 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
00380                 return NT_STATUS_BUFFER_TOO_SMALL;
00381         }
00382 
00383         if (auth_info.auth_type != RPC_SCHANNEL_AUTH_TYPE) {
00384                 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
00385                         auth_info.auth_type));
00386                 return NT_STATUS_BUFFER_TOO_SMALL;
00387         }
00388 
00389         if(!smb_io_rpc_auth_schannel_chk("", RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
00390                                 &schannel_chk, current_pdu, 0)) {
00391                 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshal RPC_AUTH_SCHANNEL_CHK.\n"));
00392                 return NT_STATUS_BUFFER_TOO_SMALL;
00393         }
00394 
00395         if (!schannel_decode(schannel_auth,
00396                         cli->auth.auth_level,
00397                         SENDER_IS_ACCEPTOR,
00398                         &schannel_chk,
00399                         prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN,
00400                         data_len)) {
00401                 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
00402                                 "Connection to remote machine %s "
00403                                 "pipe %s fnum 0x%x.\n",
00404                                 cli->cli->desthost,
00405                                 cli->pipe_name,
00406                                 (unsigned int)cli->fnum ));
00407                 return NT_STATUS_INVALID_PARAMETER;
00408         }
00409 
00410         /* The sequence number gets incremented on both send and receive. */
00411         schannel_auth->seq_num++;
00412 
00413         /*
00414          * Return the current pointer to the data offset.
00415          */
00416 
00417         if(!prs_set_offset(current_pdu, save_offset)) {
00418                 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
00419                         (unsigned int)save_offset ));
00420                 return NT_STATUS_BUFFER_TOO_SMALL;
00421         }
00422 
00423         /*
00424          * Remember the padding length. We must remove it from the real data
00425          * stream once the sign/seal is done.
00426          */
00427 
00428         *p_ss_padding_len = auth_info.auth_pad_len;
00429 
00430         return NT_STATUS_OK;
00431 }

static NTSTATUS cli_pipe_validate_rpc_response ( struct rpc_pipe_client cli,
RPC_HDR prhdr,
prs_struct current_pdu,
uint8 *  p_ss_padding_len 
) [static]

cli_pipe.c437 行で定義されています。

参照先 rpc_hdr_info::auth_lenclicli_pipe_verify_ntlmssp()cli_pipe_verify_schannel()cli_state::desthostrpc_hdr_info::frag_lenPIPE_AUTH_TYPE_KRB5PIPE_AUTH_TYPE_NONEPIPE_AUTH_TYPE_NTLMSSPPIPE_AUTH_TYPE_SCHANNELPIPE_AUTH_TYPE_SPNEGO_KRB5PIPE_AUTH_TYPE_SPNEGO_NTLMSSP.

参照元 cli_pipe_validate_current_pdu().

00440 {
00441         NTSTATUS ret = NT_STATUS_OK;
00442 
00443         /* Paranioa checks for auth_len. */
00444         if (prhdr->auth_len) {
00445                 if (prhdr->auth_len > prhdr->frag_len) {
00446                         return NT_STATUS_INVALID_PARAMETER;
00447                 }
00448 
00449                 if (prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_len ||
00450                                 prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
00451                         /* Integer wrap attempt. */
00452                         return NT_STATUS_INVALID_PARAMETER;
00453                 }
00454         }
00455 
00456         /*
00457          * Now we have a complete RPC request PDU fragment, try and verify any auth data.
00458          */
00459 
00460         switch(cli->auth.auth_type) {
00461                 case PIPE_AUTH_TYPE_NONE:
00462                         if (prhdr->auth_len) {
00463                                 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection to remote machine %s "
00464                                         "pipe %s fnum 0x%x - got non-zero auth len %u.\n",
00465                                         cli->cli->desthost,
00466                                         cli->pipe_name,
00467                                         (unsigned int)cli->fnum,
00468                                         (unsigned int)prhdr->auth_len ));
00469                                 return NT_STATUS_INVALID_PARAMETER;
00470                         }
00471                         break;
00472 
00473                 case PIPE_AUTH_TYPE_NTLMSSP:
00474                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
00475                         ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
00476                         if (!NT_STATUS_IS_OK(ret)) {
00477                                 return ret;
00478                         }
00479                         break;
00480 
00481                 case PIPE_AUTH_TYPE_SCHANNEL:
00482                         ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
00483                         if (!NT_STATUS_IS_OK(ret)) {
00484                                 return ret;
00485                         }
00486                         break;
00487 
00488                 case PIPE_AUTH_TYPE_KRB5:
00489                 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
00490                 default:
00491                         DEBUG(3, ("cli_pipe_validate_rpc_response: Connection to remote machine %s "
00492                                 "pipe %s fnum %x - unknown internal auth type %u.\n",
00493                                 cli->cli->desthost,
00494                                 cli->pipe_name,
00495                                 (unsigned int)cli->fnum,
00496                                 cli->auth.auth_type ));
00497                         return NT_STATUS_INVALID_INFO_CLASS;
00498         }
00499 
00500         return NT_STATUS_OK;
00501 }

static NTSTATUS cli_pipe_validate_current_pdu ( struct rpc_pipe_client cli,
RPC_HDR prhdr,
prs_struct current_pdu,
uint8  expected_pkt_type,
char **  ppdata,
uint32 *  pdata_len,
prs_struct return_data 
) [static]

cli_pipe.c507 行で定義されています。

参照先 rpc_hdr_resp_info::alloc_hintrpc_hdr_info::auth_lenclicli_pipe_validate_rpc_response()dcerpc_errstr()cli_state::desthostrpc_hdr_info::flagsrpc_hdr_info::frag_lenrpc_hdr_info::pkt_typeRPC_ALTCONTRESPRPC_BINDACKRPC_BINDNACKRPC_FAULTRPC_RESPONSEsmb_io_rpc_hdr_fault()smb_io_rpc_hdr_resp()rpc_hdr_fault_info::status.

参照元 rpc_api_pipe().

00513 {
00514 
00515         NTSTATUS ret = NT_STATUS_OK;
00516         uint32 current_pdu_len = prs_data_size(current_pdu);
00517 
00518         if (current_pdu_len != prhdr->frag_len) {
00519                 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
00520                         (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
00521                 return NT_STATUS_INVALID_PARAMETER;
00522         }
00523 
00524         /*
00525          * Point the return values at the real data including the RPC
00526          * header. Just in case the caller wants it.
00527          */
00528         *ppdata = prs_data_p(current_pdu);
00529         *pdata_len = current_pdu_len;
00530 
00531         /* Ensure we have the correct type. */
00532         switch (prhdr->pkt_type) {
00533                 case RPC_ALTCONTRESP:
00534                 case RPC_BINDACK:
00535 
00536                         /* Alter context and bind ack share the same packet definitions. */
00537                         break;
00538 
00539 
00540                 case RPC_RESPONSE:
00541                 {
00542                         RPC_HDR_RESP rhdr_resp;
00543                         uint8 ss_padding_len = 0;
00544 
00545                         if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
00546                                 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
00547                                 return NT_STATUS_BUFFER_TOO_SMALL;
00548                         }
00549 
00550                         /* Here's where we deal with incoming sign/seal. */
00551                         ret = cli_pipe_validate_rpc_response(cli, prhdr,
00552                                         current_pdu, &ss_padding_len);
00553                         if (!NT_STATUS_IS_OK(ret)) {
00554                                 return ret;
00555                         }
00556 
00557                         /* Point the return values at the NDR data. Remember to remove any ss padding. */
00558                         *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
00559 
00560                         if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
00561                                 return NT_STATUS_BUFFER_TOO_SMALL;
00562                         }
00563 
00564                         *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
00565 
00566                         /* Remember to remove the auth footer. */
00567                         if (prhdr->auth_len) {
00568                                 /* We've already done integer wrap tests on auth_len in
00569                                         cli_pipe_validate_rpc_response(). */
00570                                 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
00571                                         return NT_STATUS_BUFFER_TOO_SMALL;
00572                                 }
00573                                 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
00574                         }
00575 
00576                         DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
00577                                 current_pdu_len, *pdata_len, ss_padding_len ));
00578 
00579                         /*
00580                          * If this is the first reply, and the allocation hint is reasonably, try and
00581                          * set up the return_data parse_struct to the correct size.
00582                          */
00583 
00584                         if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
00585                                 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
00586                                         DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
00587                                                 "too large to allocate\n",
00588                                                 (unsigned int)rhdr_resp.alloc_hint ));
00589                                         return NT_STATUS_NO_MEMORY;
00590                                 }
00591                         }
00592 
00593                         break;
00594                 }
00595 
00596                 case RPC_BINDNACK:
00597                         DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK received from remote machine %s "
00598                                 "pipe %s fnum 0x%x!\n",
00599                                 cli->cli->desthost,
00600                                 cli->pipe_name,
00601                                 (unsigned int)cli->fnum));
00602                         /* Use this for now... */
00603                         return NT_STATUS_NETWORK_ACCESS_DENIED;
00604 
00605                 case RPC_FAULT:
00606                 {
00607                         RPC_HDR_RESP rhdr_resp;
00608                         RPC_HDR_FAULT fault_resp;
00609 
00610                         if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
00611                                 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
00612                                 return NT_STATUS_BUFFER_TOO_SMALL;
00613                         }
00614 
00615                         if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
00616                                 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
00617                                 return NT_STATUS_BUFFER_TOO_SMALL;
00618                         }
00619 
00620                         DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault code %s received from remote machine %s "
00621                                 "pipe %s fnum 0x%x!\n",
00622                                 dcerpc_errstr(NT_STATUS_V(fault_resp.status)),
00623                                 cli->cli->desthost,
00624                                 cli->pipe_name,
00625                                 (unsigned int)cli->fnum));
00626                         if (NT_STATUS_IS_OK(fault_resp.status)) {
00627                                 return NT_STATUS_UNSUCCESSFUL;
00628                         } else {
00629                                 return fault_resp.status;
00630                         }
00631                         
00632                 }
00633 
00634                 default:
00635                         DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
00636                                 "from remote machine %s pipe %s fnum 0x%x!\n",
00637                                 (unsigned int)prhdr->pkt_type,
00638                                 cli->cli->desthost,
00639                                 cli->pipe_name,
00640                                 (unsigned int)cli->fnum));
00641                         return NT_STATUS_INVALID_INFO_CLASS;
00642         }
00643 
00644         if (prhdr->pkt_type != expected_pkt_type) {
00645                 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to remote machine %s "
00646                         "pipe %s fnum %x got an unexpected RPC packet "
00647                         "type - %u, not %u\n",
00648                         cli->cli->desthost,
00649                         cli->pipe_name,
00650                         (unsigned int)cli->fnum,
00651                         prhdr->pkt_type,
00652                         expected_pkt_type));
00653                 return NT_STATUS_INVALID_INFO_CLASS;
00654         }
00655 
00656         /* Do this just before return - we don't want to modify any rpc header
00657            data before now as we may have needed to do cryptographic actions on
00658            it before. */
00659 
00660         if ((prhdr->pkt_type == RPC_BINDACK) && !(prhdr->flags & RPC_FLG_LAST)) {
00661                 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
00662                         "setting fragment first/last ON.\n"));
00663                 prhdr->flags |= RPC_FLG_FIRST|RPC_FLG_LAST;
00664         }
00665 
00666         return NT_STATUS_OK;
00667 }

static NTSTATUS cli_pipe_reset_current_pdu ( struct rpc_pipe_client cli,
RPC_HDR prhdr,
prs_struct current_pdu 
) [static]

cli_pipe.c676 行で定義されています。

参照先 rpc_hdr_info::frag_lenprs_init()prs_mem_free().

参照元 rpc_api_pipe().

00677 {
00678         uint32 current_pdu_len = prs_data_size(current_pdu);
00679 
00680         if (current_pdu_len < prhdr->frag_len) {
00681                 return NT_STATUS_BUFFER_TOO_SMALL;
00682         }
00683 
00684         /* Common case. */
00685         if (current_pdu_len == (uint32)prhdr->frag_len) {
00686                 prs_mem_free(current_pdu);
00687                 prs_init(current_pdu, 0, prs_get_mem_context(current_pdu), UNMARSHALL);
00688                 /* Make current_pdu dynamic with no memory. */
00689                 prs_give_memory(current_pdu, 0, 0, True);
00690                 return NT_STATUS_OK;
00691         }
00692 
00693         /*
00694          * Oh no ! More data in buffer than we processed in current pdu.
00695          * Cheat. Move the data down and shrink the buffer.
00696          */
00697 
00698         memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
00699                         current_pdu_len - prhdr->frag_len);
00700 
00701         /* Remember to set the read offset back to zero. */
00702         prs_set_offset(current_pdu, 0);
00703 
00704         /* Shrink the buffer. */
00705         if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
00706                 return NT_STATUS_BUFFER_TOO_SMALL;
00707         }
00708 
00709         return NT_STATUS_OK;
00710 }

static NTSTATUS rpc_api_pipe ( struct rpc_pipe_client cli,
prs_struct data,
prs_struct rbuf,
uint8  expected_pkt_type 
) [static]

cli_pipe.c738 行で定義されています。

参照先 _prs_struct::bigendian_dataclicli_api_pipe()cli_errstr()cli_get_nt_error()cli_pipe_get_current_pdu()cli_pipe_reset_current_pdu()cli_pipe_validate_current_pdu()cli_state::desthosterrrpc_hdr_info::flagsrpc_hdr_info::pack_typeprs_init()prs_mem_free().

参照元 rpc_api_pipe_req()rpc_finish_spnego_ntlmssp_bind()rpc_pipe_bind().

00742 {
00743         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
00744         char *rparam = NULL;
00745         uint32 rparam_len = 0;
00746         uint16 setup[2];
00747         char *pdata = prs_data_p(data);
00748         uint32 data_len = prs_offset(data);
00749         char *prdata = NULL;
00750         uint32 rdata_len = 0;
00751         uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : RPC_MAX_PDU_FRAG_LEN;
00752         uint32 current_rbuf_offset = 0;
00753         prs_struct current_pdu;
00754         
00755 #ifdef DEVELOPER
00756         /* Ensure we're not sending too much. */
00757         SMB_ASSERT(data_len <= max_data);
00758 #endif
00759 
00760         /* Set up the current pdu parse struct. */
00761         prs_init(&current_pdu, 0, prs_get_mem_context(rbuf), UNMARSHALL);
00762 
00763         /* Create setup parameters - must be in native byte order. */
00764         setup[0] = TRANSACT_DCERPCCMD; 
00765         setup[1] = cli->fnum; /* Pipe file handle. */
00766 
00767         DEBUG(5,("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x\n",
00768                 cli->cli->desthost,
00769                 cli->pipe_name,
00770                 (unsigned int)cli->fnum ));
00771 
00772         /*
00773          * Send the last (or only) fragment of an RPC request. For small
00774          * amounts of data (about 1024 bytes or so) the RPC request and response
00775          * appears in a SMBtrans request and response.
00776          */
00777 
00778         if (!cli_api_pipe(cli->cli, "\\PIPE\\",
00779                   setup, 2, 0,                     /* Setup, length, max */
00780                   NULL, 0, 0,                      /* Params, length, max */
00781                   pdata, data_len, max_data,       /* data, length, max */
00782                   &rparam, &rparam_len,            /* return params, len */
00783                   &prdata, &rdata_len))            /* return data, len */
00784         {
00785                 DEBUG(0, ("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x"
00786                         "returned critical error. Error was %s\n",
00787                         cli->cli->desthost,
00788                         cli->pipe_name,
00789                         (unsigned int)cli->fnum,
00790                         cli_errstr(cli->cli)));
00791                 ret = cli_get_nt_error(cli->cli);
00792                 SAFE_FREE(rparam);
00793                 SAFE_FREE(prdata);
00794                 goto err;
00795         }
00796 
00797         /* Throw away returned params - we know we won't use them. */
00798 
00799         SAFE_FREE(rparam);
00800 
00801         if (prdata == NULL) {
00802                 DEBUG(3,("rpc_api_pipe: Remote machine %s pipe %s "
00803                         "fnum 0x%x failed to return data.\n",
00804                         cli->cli->desthost,
00805                         cli->pipe_name,
00806                         (unsigned int)cli->fnum));
00807                 /* Yes - some calls can truely return no data... */
00808                 prs_mem_free(&current_pdu);
00809                 return NT_STATUS_OK;
00810         }
00811 
00812         /*
00813          * Give this memory as dynamic to the current pdu.
00814          */
00815 
00816         prs_give_memory(&current_pdu, prdata, rdata_len, True);
00817 
00818         /* Ensure we can mess with the return prs_struct. */
00819         SMB_ASSERT(UNMARSHALLING(rbuf));
00820         SMB_ASSERT(prs_data_size(rbuf) == 0);
00821 
00822         /* Make rbuf dynamic with no memory. */
00823         prs_give_memory(rbuf, 0, 0, True);
00824 
00825         while(1) {
00826                 RPC_HDR rhdr;
00827                 char *ret_data;
00828                 uint32 ret_data_len;
00829 
00830                 /* Ensure we have enough data for a pdu. */
00831                 ret = cli_pipe_get_current_pdu(cli, &rhdr, &current_pdu);
00832                 if (!NT_STATUS_IS_OK(ret)) {
00833                         goto err;
00834                 }
00835 
00836                 /* We pass in rbuf here so if the alloc hint is set correctly 
00837                    we can set the output size and avoid reallocs. */
00838 
00839                 ret = cli_pipe_validate_current_pdu(cli, &rhdr, &current_pdu, expected_pkt_type,
00840                                 &ret_data, &ret_data_len, rbuf);
00841 
00842                 DEBUG(10,("rpc_api_pipe: got PDU len of %u at offset %u\n",
00843                         prs_data_size(&current_pdu), current_rbuf_offset ));
00844 
00845                 if (!NT_STATUS_IS_OK(ret)) {
00846                         goto err;
00847                 }
00848 
00849                 if ((rhdr.flags & RPC_FLG_FIRST)) {
00850                         if (rhdr.pack_type[0] == 0) {
00851                                 /* Set the data type correctly for big-endian data on the first packet. */
00852                                 DEBUG(10,("rpc_api_pipe: On machine %s pipe %s fnum 0x%x "
00853                                         "PDU data format is big-endian.\n",
00854                                         cli->cli->desthost,
00855                                         cli->pipe_name,
00856                                         (unsigned int)cli->fnum));
00857 
00858                                 prs_set_endian_data(rbuf, RPC_BIG_ENDIAN);
00859                         } else {
00860                                 /* Check endianness on subsequent packets. */
00861                                 if (current_pdu.bigendian_data != rbuf->bigendian_data) {
00862                                         DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to %s\n",
00863                                                 rbuf->bigendian_data ? "big" : "little",
00864                                                 current_pdu.bigendian_data ? "big" : "little" ));
00865                                         ret = NT_STATUS_INVALID_PARAMETER;
00866                                         goto err;
00867                                 }
00868                         }
00869                 }
00870 
00871                 /* Now copy the data portion out of the pdu into rbuf. */
00872                 if (!prs_force_grow(rbuf, ret_data_len)) {
00873                         ret = NT_STATUS_NO_MEMORY;
00874                         goto err;
00875                 }
00876                 memcpy(prs_data_p(rbuf)+current_rbuf_offset, ret_data, (size_t)ret_data_len);
00877                 current_rbuf_offset += ret_data_len;
00878 
00879                 /* See if we've finished with all the data in current_pdu yet ? */
00880                 ret = cli_pipe_reset_current_pdu(cli, &rhdr, &current_pdu);
00881                 if (!NT_STATUS_IS_OK(ret)) {
00882                         goto err;
00883                 }
00884 
00885                 if (rhdr.flags & RPC_FLG_LAST) {
00886                         break; /* We're done. */
00887                 }
00888         }
00889 
00890         DEBUG(10,("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x returned %u bytes.\n",
00891                 cli->cli->desthost,
00892                 cli->pipe_name,
00893                 (unsigned int)cli->fnum,
00894                 (unsigned int)prs_data_size(rbuf) ));
00895 
00896         prs_mem_free(&current_pdu);
00897         return NT_STATUS_OK;
00898 
00899   err:
00900 
00901         prs_mem_free(&current_pdu);
00902         prs_mem_free(rbuf);
00903         return ret;
00904 }

static NTSTATUS create_krb5_auth_bind_req ( struct rpc_pipe_client cli,
enum pipe_auth_level  auth_level,
RPC_HDR_AUTH pauth_out,
prs_struct auth_data 
) [static]

cli_pipe.c910 行で定義されています。

参照先 clicli_krb5_get_ticket()data_blob_::datadata_blob()data_blob_free()dump_data()init_rpc_hdr_auth()data_blob_::lengthprs_mem_free()kerberos_auth_struct::service_principalkerberos_auth_struct::session_keyspnego_gen_krb5_wrap().

参照元 create_rpc_bind_req().

00914 {
00915 #ifdef HAVE_KRB5
00916         int ret;
00917         struct kerberos_auth_struct *a = cli->auth.a_u.kerberos_auth;
00918         DATA_BLOB tkt = data_blob(NULL, 0);
00919         DATA_BLOB tkt_wrapped = data_blob(NULL, 0);
00920 
00921         /* We may change the pad length before marshalling. */
00922         init_rpc_hdr_auth(pauth_out, RPC_KRB5_AUTH_TYPE, (int)auth_level, 0, 1);
00923 
00924         DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
00925                 a->service_principal ));
00926 
00927         /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
00928 
00929         ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
00930                         &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL);
00931 
00932         if (ret) {
00933                 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
00934                         "failed with %s\n",
00935                         a->service_principal,
00936                         error_message(ret) ));
00937 
00938                 data_blob_free(&tkt);
00939                 prs_mem_free(auth_data);
00940                 return NT_STATUS_INVALID_PARAMETER;
00941         }
00942 
00943         /* wrap that up in a nice GSS-API wrapping */
00944         tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
00945 
00946         data_blob_free(&tkt);
00947 
00948         /* Auth len in the rpc header doesn't include auth_header. */
00949         if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
00950                 data_blob_free(&tkt_wrapped);
00951                 prs_mem_free(auth_data);
00952                 return NT_STATUS_NO_MEMORY;
00953         }
00954 
00955         DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
00956         dump_data(5, (const char *)tkt_wrapped.data, tkt_wrapped.length);
00957 
00958         data_blob_free(&tkt_wrapped);
00959         return NT_STATUS_OK;
00960 #else
00961         return NT_STATUS_INVALID_PARAMETER;
00962 #endif
00963 }

static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req ( struct rpc_pipe_client cli,
enum pipe_auth_level  auth_level,
RPC_HDR_AUTH pauth_out,
prs_struct auth_data 
) [static]

cli_pipe.c969 行で定義されています。

参照先 clidata_blob_::datadata_blob()data_blob_free()dump_data()gen_negTokenInit()init_rpc_hdr_auth()data_blob_::lengthntlmssp_update()prs_mem_free().

参照元 create_rpc_bind_req().

00973 {
00974         NTSTATUS nt_status;
00975         DATA_BLOB null_blob = data_blob(NULL, 0);
00976         DATA_BLOB request = data_blob(NULL, 0);
00977         DATA_BLOB spnego_msg = data_blob(NULL, 0);
00978 
00979         /* We may change the pad length before marshalling. */
00980         init_rpc_hdr_auth(pauth_out, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
00981 
00982         DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
00983         nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state,
00984                                         null_blob,
00985                                         &request);
00986 
00987         if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
00988                 data_blob_free(&request);
00989                 prs_mem_free(auth_data);
00990                 return nt_status;
00991         }
00992 
00993         /* Wrap this in SPNEGO. */
00994         spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
00995 
00996         data_blob_free(&request);
00997 
00998         /* Auth len in the rpc header doesn't include auth_header. */
00999         if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
01000                 data_blob_free(&spnego_msg);
01001                 prs_mem_free(auth_data);
01002                 return NT_STATUS_NO_MEMORY;
01003         }
01004 
01005         DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
01006         dump_data(5, (const char *)spnego_msg.data, spnego_msg.length);
01007 
01008         data_blob_free(&spnego_msg);
01009         return NT_STATUS_OK;
01010 }

static NTSTATUS create_ntlmssp_auth_rpc_bind_req ( struct rpc_pipe_client cli,
enum pipe_auth_level  auth_level,
RPC_HDR_AUTH pauth_out,
prs_struct auth_data 
) [static]

cli_pipe.c1016 行で定義されています。

参照先 clidata_blob_::datadata_blob()data_blob_free()dump_data()init_rpc_hdr_auth()data_blob_::lengthntlmssp_update()prs_mem_free().

参照元 create_rpc_bind_req().

01020 {
01021         NTSTATUS nt_status;
01022         DATA_BLOB null_blob = data_blob(NULL, 0);
01023         DATA_BLOB request = data_blob(NULL, 0);
01024 
01025         /* We may change the pad length before marshalling. */
01026         init_rpc_hdr_auth(pauth_out, RPC_NTLMSSP_AUTH_TYPE, (int)auth_level, 0, 1);
01027 
01028         DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
01029         nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state,
01030                                         null_blob,
01031                                         &request);
01032 
01033         if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
01034                 data_blob_free(&request);
01035                 prs_mem_free(auth_data);
01036                 return nt_status;
01037         }
01038 
01039         /* Auth len in the rpc header doesn't include auth_header. */
01040         if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
01041                 data_blob_free(&request);
01042                 prs_mem_free(auth_data);
01043                 return NT_STATUS_NO_MEMORY;
01044         }
01045 
01046         DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
01047         dump_data(5, (const char *)request.data, request.length);
01048 
01049         data_blob_free(&request);
01050         return NT_STATUS_OK;
01051 }

static NTSTATUS create_schannel_auth_rpc_bind_req ( struct rpc_pipe_client cli,
enum pipe_auth_level  auth_level,
RPC_HDR_AUTH pauth_out,
prs_struct auth_data 
) [static]

cli_pipe.c1057 行で定義されています。

参照先 clicli_state::domainglobal_mynameinit_rpc_auth_schannel_neg()init_rpc_hdr_auth()lp_workgroup()prs_mem_free()smb_io_rpc_auth_schannel_neg().

参照元 create_rpc_bind_req().

01061 {
01062         RPC_AUTH_SCHANNEL_NEG schannel_neg;
01063 
01064         /* We may change the pad length before marshalling. */
01065         init_rpc_hdr_auth(pauth_out, RPC_SCHANNEL_AUTH_TYPE, (int)auth_level, 0, 1);
01066 
01067         /* Use lp_workgroup() if domain not specified */
01068 
01069         if (!cli->domain || !cli->domain[0]) {
01070                 cli->domain = lp_workgroup();
01071         }
01072 
01073         init_rpc_auth_schannel_neg(&schannel_neg, cli->domain, global_myname());
01074 
01075         /*
01076          * Now marshall the data into the auth parse_struct.
01077          */
01078 
01079         if(!smb_io_rpc_auth_schannel_neg("schannel_neg",
01080                                        &schannel_neg, auth_data, 0)) {
01081                 DEBUG(0,("Failed to marshall RPC_AUTH_SCHANNEL_NEG.\n"));
01082                 prs_mem_free(auth_data);
01083                 return NT_STATUS_NO_MEMORY;
01084         }
01085 
01086         return NT_STATUS_OK;
01087 }

static NTSTATUS create_bind_or_alt_ctx_internal ( enum RPC_PKT_TYPE  pkt_type,
prs_struct rpc_out,
uint32  rpc_call_id,
RPC_IFACE abstract,
RPC_IFACE transfer,
RPC_HDR_AUTH phdr_auth,
prs_struct pauth_info 
) [static]

cli_pipe.c1093 行で定義されています。

参照先 rpc_hdr_auth_info::auth_pad_leninit_rpc_context()init_rpc_hdr()init_rpc_hdr_rb()smb_io_rpc_hdr()smb_io_rpc_hdr_auth()smb_io_rpc_hdr_rb().

参照元 create_rpc_alter_context()create_rpc_bind_req().

01100 {
01101         RPC_HDR hdr;
01102         RPC_HDR_RB hdr_rb;
01103         RPC_CONTEXT rpc_ctx;
01104         uint16 auth_len = prs_offset(pauth_info);
01105         uint8 ss_padding_len = 0;
01106         uint16 frag_len = 0;
01107 
01108         /* create the RPC context. */
01109         init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
01110 
01111         /* create the bind request RPC_HDR_RB */
01112         init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
01113 
01114         /* Start building the frag length. */
01115         frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
01116 
01117         /* Do we need to pad ? */
01118         if (auth_len) {
01119                 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
01120                 if (data_len % 8) {
01121                         ss_padding_len = 8 - (data_len % 8);
01122                         phdr_auth->auth_pad_len = ss_padding_len;
01123                 }
01124                 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
01125         }
01126 
01127         /* Create the request RPC_HDR */
01128         init_rpc_hdr(&hdr, pkt_type, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id, frag_len, auth_len);
01129 
01130         /* Marshall the RPC header */
01131         if(!smb_io_rpc_hdr("hdr"   , &hdr, rpc_out, 0)) {
01132                 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
01133                 return NT_STATUS_NO_MEMORY;
01134         }
01135 
01136         /* Marshall the bind request data */
01137         if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
01138                 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
01139                 return NT_STATUS_NO_MEMORY;
01140         }
01141 
01142         /*
01143          * Grow the outgoing buffer to store any auth info.
01144          */
01145 
01146         if(auth_len != 0) {
01147                 if (ss_padding_len) {
01148                         char pad[8];
01149                         memset(pad, '\0', 8);
01150                         if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
01151                                 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
01152                                 return NT_STATUS_NO_MEMORY;
01153                         }
01154                 }
01155 
01156                 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
01157                         DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
01158                         return NT_STATUS_NO_MEMORY;
01159                 }
01160 
01161 
01162                 if(!prs_append_prs_data( rpc_out, pauth_info)) {
01163                         DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
01164                         return NT_STATUS_NO_MEMORY;
01165                 }
01166         }
01167 
01168         return NT_STATUS_OK;
01169 }

static NTSTATUS create_rpc_bind_req ( struct rpc_pipe_client cli,
prs_struct rpc_out,
uint32  rpc_call_id,
RPC_IFACE abstract,
RPC_IFACE transfer,
enum pipe_auth_type  auth_type,
enum pipe_auth_level  auth_level 
) [static]

cli_pipe.c1175 行で定義されています。

参照先 clicreate_bind_or_alt_ctx_internal()create_krb5_auth_bind_req()create_ntlmssp_auth_rpc_bind_req()create_schannel_auth_rpc_bind_req()create_spnego_ntlmssp_auth_rpc_bind_req()PIPE_AUTH_TYPE_KRB5PIPE_AUTH_TYPE_NONEPIPE_AUTH_TYPE_NTLMSSPPIPE_AUTH_TYPE_SCHANNELPIPE_AUTH_TYPE_SPNEGO_NTLMSSPprs_init()prs_mem_free()RPC_BIND.

参照元 rpc_pipe_bind().

01181 {
01182         RPC_HDR_AUTH hdr_auth;
01183         prs_struct auth_info;
01184         NTSTATUS ret = NT_STATUS_OK;
01185 
01186         ZERO_STRUCT(hdr_auth);
01187         prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL);
01188 
01189         switch (auth_type) {
01190                 case PIPE_AUTH_TYPE_SCHANNEL:
01191                         ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
01192                         if (!NT_STATUS_IS_OK(ret)) {
01193                                 prs_mem_free(&auth_info);
01194                                 return ret;
01195                         }
01196                         break;
01197 
01198                 case PIPE_AUTH_TYPE_NTLMSSP:
01199                         ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
01200                         if (!NT_STATUS_IS_OK(ret)) {
01201                                 prs_mem_free(&auth_info);
01202                                 return ret;
01203                         }
01204                         break;
01205 
01206                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
01207                         ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
01208                         if (!NT_STATUS_IS_OK(ret)) {
01209                                 prs_mem_free(&auth_info);
01210                                 return ret;
01211                         }
01212                         break;
01213 
01214                 case PIPE_AUTH_TYPE_KRB5:
01215                         ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
01216                         if (!NT_STATUS_IS_OK(ret)) {
01217                                 prs_mem_free(&auth_info);
01218                                 return ret;
01219                         }
01220                         break;
01221 
01222                 case PIPE_AUTH_TYPE_NONE:
01223                         break;
01224 
01225                 default:
01226                         /* "Can't" happen. */
01227                         return NT_STATUS_INVALID_INFO_CLASS;
01228         }
01229 
01230         ret = create_bind_or_alt_ctx_internal(RPC_BIND,
01231                                                 rpc_out, 
01232                                                 rpc_call_id,
01233                                                 abstract,
01234                                                 transfer,
01235                                                 &hdr_auth,
01236                                                 &auth_info);
01237 
01238         prs_mem_free(&auth_info);
01239         return ret;
01240 }

static NTSTATUS add_ntlmssp_auth_footer ( struct rpc_pipe_client cli,
RPC_HDR phdr,
uint32  ss_padding_len,
prs_struct outgoing_pdu 
) [static]

cli_pipe.c1246 行で定義されています。

参照先 clidata_blob_::datadata_blob()data_blob_free()init_rpc_hdr_auth()map_pipe_auth_type_to_rpc_auth_type()ntlmssp_seal_packet()ntlmssp_sign_packet()PIPE_AUTH_LEVEL_INTEGRITYPIPE_AUTH_LEVEL_PRIVACYsmb_io_rpc_hdr_auth()smb_panic()status.

参照元 rpc_api_pipe_req().

01250 {
01251         RPC_HDR_AUTH auth_info;
01252         NTSTATUS status;
01253         DATA_BLOB auth_blob = data_blob(NULL, 0);
01254         uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
01255 
01256         if (!cli->auth.a_u.ntlmssp_state) {
01257                 return NT_STATUS_INVALID_PARAMETER;
01258         }
01259 
01260         /* Init and marshall the auth header. */
01261         init_rpc_hdr_auth(&auth_info,
01262                         map_pipe_auth_type_to_rpc_auth_type(cli->auth.auth_type),
01263                         cli->auth.auth_level,
01264                         ss_padding_len,
01265                         1 /* context id. */);
01266 
01267         if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
01268                 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
01269                 data_blob_free(&auth_blob);
01270                 return NT_STATUS_NO_MEMORY;
01271         }
01272 
01273         switch (cli->auth.auth_level) {
01274                 case PIPE_AUTH_LEVEL_PRIVACY:
01275                         /* Data portion is encrypted. */
01276                         status = ntlmssp_seal_packet(cli->auth.a_u.ntlmssp_state,
01277                                         (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
01278                                         data_and_pad_len,
01279                                         (unsigned char *)prs_data_p(outgoing_pdu),
01280                                         (size_t)prs_offset(outgoing_pdu),
01281                                         &auth_blob);
01282                         if (!NT_STATUS_IS_OK(status)) {
01283                                 data_blob_free(&auth_blob);
01284                                 return status;
01285                         }
01286                         break;
01287 
01288                 case PIPE_AUTH_LEVEL_INTEGRITY:
01289                         /* Data is signed. */
01290                         status = ntlmssp_sign_packet(cli->auth.a_u.ntlmssp_state,
01291                                         (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
01292                                         data_and_pad_len,
01293                                         (unsigned char *)prs_data_p(outgoing_pdu),
01294                                         (size_t)prs_offset(outgoing_pdu),
01295                                         &auth_blob);
01296                         if (!NT_STATUS_IS_OK(status)) {
01297                                 data_blob_free(&auth_blob);
01298                                 return status;
01299                         }
01300                         break;
01301 
01302                 default:
01303                         /* Can't happen. */
01304                         smb_panic("bad auth level");
01305                         /* Notreached. */
01306                         return NT_STATUS_INVALID_PARAMETER;
01307         }
01308 
01309         /* Finally marshall the blob. */
01310                                                                                                        
01311         if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
01312                 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
01313                         (unsigned int)NTLMSSP_SIG_SIZE));
01314                 data_blob_free(&auth_blob);
01315                 return NT_STATUS_NO_MEMORY;
01316         }
01317                                                                                                                                 
01318         data_blob_free(&auth_blob);
01319         return NT_STATUS_OK;
01320 }

static NTSTATUS add_schannel_auth_footer ( struct rpc_pipe_client cli,
RPC_HDR phdr,
uint32  ss_padding_len,
prs_struct outgoing_pdu 
) [static]

cli_pipe.c1326 行で定義されています。

参照先 cliinit_rpc_hdr_auth()map_pipe_auth_type_to_rpc_auth_type()PIPE_AUTH_LEVEL_INTEGRITYPIPE_AUTH_LEVEL_PRIVACYSENDER_IS_INITIATORschannel_auth_struct::seq_numsmb_io_rpc_auth_schannel_chk()smb_io_rpc_hdr_auth()smb_panic().

参照元 rpc_api_pipe_req().

01330 {
01331         RPC_HDR_AUTH auth_info;
01332         RPC_AUTH_SCHANNEL_CHK verf;
01333         struct schannel_auth_struct *sas = cli->auth.a_u.schannel_auth;
01334         char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
01335         size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
01336 
01337         if (!sas) {
01338                 return NT_STATUS_INVALID_PARAMETER;
01339         }
01340 
01341         /* Init and marshall the auth header. */
01342         init_rpc_hdr_auth(&auth_info,
01343                         map_pipe_auth_type_to_rpc_auth_type(cli->auth.auth_type),
01344                         cli->auth.auth_level,
01345                         ss_padding_len,
01346                         1 /* context id. */);
01347 
01348         if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
01349                 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
01350                 return NT_STATUS_NO_MEMORY;
01351         }
01352 
01353         switch (cli->auth.auth_level) {
01354                 case PIPE_AUTH_LEVEL_PRIVACY:
01355                 case PIPE_AUTH_LEVEL_INTEGRITY:
01356                         DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
01357                                 sas->seq_num));
01358 
01359                         schannel_encode(sas,
01360                                         cli->auth.auth_level,
01361                                         SENDER_IS_INITIATOR,
01362                                         &verf,
01363                                         data_p,
01364                                         data_and_pad_len);
01365 
01366                         sas->seq_num++;
01367                         break;
01368 
01369                 default:
01370                         /* Can't happen. */
01371                         smb_panic("bad auth level");
01372                         /* Notreached. */
01373                         return NT_STATUS_INVALID_PARAMETER;
01374         }
01375 
01376         /* Finally marshall the blob. */
01377         smb_io_rpc_auth_schannel_chk("",
01378                         RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
01379                         &verf,
01380                         outgoing_pdu,
01381                         0);
01382                                                                                                
01383         return NT_STATUS_OK;
01384 }

static uint32 calculate_data_len_tosend ( struct rpc_pipe_client cli,
uint32  data_left,
uint16 *  p_frag_len,
uint16 *  p_auth_len,
uint32 *  p_ss_padding 
) [static]

cli_pipe.c1391 行で定義されています。

参照先 cliPIPE_AUTH_LEVEL_CONNECTPIPE_AUTH_LEVEL_INTEGRITYPIPE_AUTH_LEVEL_NONEPIPE_AUTH_LEVEL_PRIVACYPIPE_AUTH_TYPE_NTLMSSPPIPE_AUTH_TYPE_SCHANNELPIPE_AUTH_TYPE_SPNEGO_NTLMSSPsmb_panic().

参照元 rpc_api_pipe_req().

01396 {
01397         uint32 data_space, data_len;
01398 
01399         switch (cli->auth.auth_level) {
01400                 case PIPE_AUTH_LEVEL_NONE:
01401                 case PIPE_AUTH_LEVEL_CONNECT:
01402                         data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
01403                         data_len = MIN(data_space, data_left);
01404                         *p_ss_padding = 0;
01405                         *p_auth_len = 0;
01406                         *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
01407                         return data_len;
01408 
01409                 case PIPE_AUTH_LEVEL_INTEGRITY:
01410                 case PIPE_AUTH_LEVEL_PRIVACY:
01411                         /* Treat the same for all authenticated rpc requests. */
01412                         switch(cli->auth.auth_type) {
01413                                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
01414                                 case PIPE_AUTH_TYPE_NTLMSSP:
01415                                         *p_auth_len = NTLMSSP_SIG_SIZE;
01416                                         break;
01417                                 case PIPE_AUTH_TYPE_SCHANNEL:
01418                                         *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
01419                                         break;
01420                                 default:
01421                                         smb_panic("bad auth type");
01422                                         break;
01423                         }
01424 
01425                         data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
01426                                                 RPC_HDR_AUTH_LEN - *p_auth_len;
01427 
01428                         data_len = MIN(data_space, data_left);
01429                         if (data_len % 8) {
01430                                 *p_ss_padding = 8 - (data_len % 8);
01431                         }
01432                         *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN +                /* Normal headers. */
01433                                         data_len + *p_ss_padding +              /* data plus padding. */
01434                                         RPC_HDR_AUTH_LEN + *p_auth_len;         /* Auth header and auth data. */
01435                         return data_len;
01436 
01437                 default:
01438                         smb_panic("bad auth level");
01439                         /* Notreached. */
01440                         return 0;
01441         }
01442 }

NTSTATUS rpc_api_pipe_req ( struct rpc_pipe_client cli,
uint8  op_num,
prs_struct in_data,
prs_struct out_data 
)

cli_pipe.c1451 行で定義されています。

参照先 add_ntlmssp_auth_footer()add_schannel_auth_footer()calculate_data_len_tosend()clicli_get_nt_error()cli_write()DEBUGLEVELdyn_LOGFILEBASEflagsrpc_hdr_info::frag_lenget_rpc_call_id()init_rpc_hdr()init_rpc_hdr_req()PIPE_AUTH_TYPE_NONEPIPE_AUTH_TYPE_NTLMSSPPIPE_AUTH_TYPE_SCHANNELPIPE_AUTH_TYPE_SPNEGO_NTLMSSPprs_dump()prs_init()prs_mem_free()rpc_api_pipe()RPC_REQUESTRPC_RESPONSEsmb_io_rpc_hdr()smb_io_rpc_hdr_req()smb_panic().

参照元 cli_do_rpc_ndr().

01455 {
01456         NTSTATUS ret;
01457         uint32 data_left = prs_offset(in_data);
01458         uint32 alloc_hint = prs_offset(in_data);
01459         uint32 data_sent_thistime = 0;
01460         uint32 current_data_offset = 0;
01461         uint32 call_id = get_rpc_call_id();
01462         char pad[8];
01463         prs_struct outgoing_pdu;
01464 
01465         memset(pad, '\0', 8);
01466 
01467         if (cli->max_xmit_frag < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
01468                 /* Server is screwed up ! */
01469                 return NT_STATUS_INVALID_PARAMETER;
01470         }
01471 
01472         prs_init(&outgoing_pdu, cli->max_xmit_frag, prs_get_mem_context(in_data), MARSHALL);
01473 
01474         while (1) {
01475                 RPC_HDR hdr;
01476                 RPC_HDR_REQ hdr_req;
01477                 uint16 auth_len = 0;
01478                 uint16 frag_len = 0;
01479                 uint8 flags = 0;
01480                 uint32 ss_padding = 0;
01481 
01482                 data_sent_thistime = calculate_data_len_tosend(cli, data_left,
01483                                                 &frag_len, &auth_len, &ss_padding);
01484 
01485                 if (current_data_offset == 0) {
01486                         flags = RPC_FLG_FIRST;
01487                 }
01488 
01489                 if (data_sent_thistime == data_left) {
01490                         flags |= RPC_FLG_LAST;
01491                 }
01492 
01493                 /* Create and marshall the header and request header. */
01494                 init_rpc_hdr(&hdr, RPC_REQUEST, flags, call_id, frag_len, auth_len);
01495 
01496                 if(!smb_io_rpc_hdr("hdr    ", &hdr, &outgoing_pdu, 0)) {
01497                         prs_mem_free(&outgoing_pdu);
01498                         return NT_STATUS_NO_MEMORY;
01499                 }
01500 
01501                 /* Create the rpc request RPC_HDR_REQ */
01502                 init_rpc_hdr_req(&hdr_req, alloc_hint, op_num);
01503 
01504                 if(!smb_io_rpc_hdr_req("hdr_req", &hdr_req, &outgoing_pdu, 0)) {
01505                         prs_mem_free(&outgoing_pdu);
01506                         return NT_STATUS_NO_MEMORY;
01507                 }
01508 
01509                 /* Copy in the data, plus any ss padding. */
01510                 if (!prs_append_some_prs_data(&outgoing_pdu, in_data, current_data_offset, data_sent_thistime)) {
01511                         prs_mem_free(&outgoing_pdu);
01512                         return NT_STATUS_NO_MEMORY;
01513                 }
01514 
01515                 /* Copy the sign/seal padding data. */
01516                 if (ss_padding) {
01517                         if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding)) {
01518                                 prs_mem_free(&outgoing_pdu);
01519                                 return NT_STATUS_NO_MEMORY;
01520                         }
01521                 }
01522 
01523                 /* Generate any auth sign/seal and add the auth footer. */
01524                 if (auth_len) {
01525                         switch (cli->auth.auth_type) {
01526                                 case PIPE_AUTH_TYPE_NONE:
01527                                         break;
01528                                 case PIPE_AUTH_TYPE_NTLMSSP:
01529                                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
01530                                         ret = add_ntlmssp_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
01531                                         if (!NT_STATUS_IS_OK(ret)) {
01532                                                 prs_mem_free(&outgoing_pdu);
01533                                                 return ret;
01534                                         }
01535                                         break;
01536                                 case PIPE_AUTH_TYPE_SCHANNEL:
01537                                         ret = add_schannel_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
01538                                         if (!NT_STATUS_IS_OK(ret)) {
01539                                                 prs_mem_free(&outgoing_pdu);
01540                                                 return ret;
01541                                         }
01542                                         break;
01543                                 default:
01544                                         smb_panic("bad auth type");
01545                                         break; /* notreached */
01546                         }
01547                 }
01548 
01549                 /* Actually send the packet. */
01550                 if (flags & RPC_FLG_LAST) {
01551                         /* Last packet - send the data, get the reply and return. */
01552                         ret = rpc_api_pipe(cli, &outgoing_pdu, out_data, RPC_RESPONSE);
01553                         prs_mem_free(&outgoing_pdu);
01554 
01555                         
01556                         if (DEBUGLEVEL >= 50) {
01557                                 pstring dump_name;
01558                                 /* Also capture received data */
01559                                 slprintf(dump_name, sizeof(dump_name) - 1, "%s/reply_%s_%d",
01560                                         dyn_LOGFILEBASE, cli->pipe_name, op_num);
01561                                 prs_dump(dump_name, op_num, out_data);
01562                         }
01563 
01564                         return ret;
01565                 } else {
01566                         /* More packets to come - write and continue. */
01567                         ssize_t num_written = cli_write(cli->cli, cli->fnum, 8, /* 8 means message mode. */
01568                                                         prs_data_p(&outgoing_pdu),
01569                                                         (off_t)0,
01570                                                         (size_t)hdr.frag_len);
01571 
01572                         if (num_written != hdr.frag_len) {
01573                                 prs_mem_free(&outgoing_pdu);
01574                                 return cli_get_nt_error(cli->cli);
01575                         }
01576                 }
01577 
01578                 current_data_offset += data_sent_thistime;
01579                 data_left -= data_sent_thistime;
01580 
01581                 /* Reset the marshalling position back to zero. */
01582                 if (!prs_set_offset(&outgoing_pdu, 0)) {
01583                         prs_mem_free(&outgoing_pdu);
01584                         return NT_STATUS_NO_MEMORY;
01585                 }
01586         }
01587 }

static BOOL rpc_pipe_set_hnd_state ( struct rpc_pipe_client cli,
const char *  pipe_name,
uint16  device_state 
) [static]

cli_pipe.c1593 行で定義されています。

参照先 clicli_api_pipe().

01595 {
01596         BOOL state_set = False;
01597         char param[2];
01598         uint16 setup[2]; /* only need 2 uint16 setup parameters */
01599         char *rparam = NULL;
01600         char *rdata = NULL;
01601         uint32 rparam_len, rdata_len;
01602 
01603         if (pipe_name == NULL)
01604                 return False;
01605 
01606         DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
01607                  cli->fnum, pipe_name, device_state));
01608 
01609         /* create parameters: device state */
01610         SSVAL(param, 0, device_state);
01611 
01612         /* create setup parameters. */
01613         setup[0] = 0x0001; 
01614         setup[1] = cli->fnum; /* pipe file handle.  got this from an SMBOpenX. */
01615 
01616         /* send the data on \PIPE\ */
01617         if (cli_api_pipe(cli->cli, "\\PIPE\\",
01618                     setup, 2, 0,                /* setup, length, max */
01619                     param, 2, 0,                /* param, length, max */
01620                     NULL, 0, 1024,              /* data, length, max */
01621                     &rparam, &rparam_len,        /* return param, length */
01622                     &rdata, &rdata_len))         /* return data, length */
01623         {
01624                 DEBUG(5, ("Set Handle state: return OK\n"));
01625                 state_set = True;
01626         }
01627 
01628         SAFE_FREE(rparam);
01629         SAFE_FREE(rdata);
01630 
01631         return state_set;
01632 }

static BOOL valid_pipe_name ( const int  pipe_idx,
RPC_IFACE abstract,
RPC_IFACE transfer 
) [static]

cli_pipe.c1639 行で定義されています。

参照先 pipe_id_info::abstr_syntaxdump_data()pipe_namespipe_id_info::trans_syntax.

参照元 rpc_pipe_bind().

01640 {
01641         if ( pipe_idx >= PI_MAX_PIPES ) {
01642                 DEBUG(0,("valid_pipe_name: Programmer error!  Invalid pipe index [%d]\n",
01643                         pipe_idx));
01644                 return False;
01645         }
01646 
01647         DEBUG(5,("Bind Abstract Syntax: "));    
01648         dump_data(5, (char*)&pipe_names[pipe_idx].abstr_syntax, 
01649                   sizeof(pipe_names[pipe_idx].abstr_syntax));
01650         DEBUG(5,("Bind Transfer Syntax: "));
01651         dump_data(5, (char*)&pipe_names[pipe_idx].trans_syntax,
01652                   sizeof(pipe_names[pipe_idx].trans_syntax));
01653 
01654         /* copy the required syntaxes out so we can do the right bind */
01655         
01656         *transfer = pipe_names[pipe_idx].trans_syntax;
01657         *abstract = pipe_names[pipe_idx].abstr_syntax;
01658 
01659         return True;
01660 }

static BOOL check_bind_response ( RPC_HDR_BA hdr_ba,
const int  pipe_idx,
RPC_IFACE transfer 
) [static]

cli_pipe.c1666 行で定義されています。

参照先 rpc_hdr_ba_info::addrpipe_id_info::client_piperpc_addr_info::lenrpc_results_info::num_resultspipe_namesrpc_results_info::reasonrpc_hdr_ba_info::resrpc_results_info::resultpipe_id_info::server_piperpc_addr_info::strstrequal()rpc_hdr_ba_info::transferrpc_iface_info::uuidrpc_iface_info::version.

参照元 rpc_pipe_bind().

01667 {
01668         if ( hdr_ba->addr.len == 0) {
01669                 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
01670         }
01671 
01672 # if 0  /* JERRY -- apparently ASU forgets to fill in the server pipe name sometimes */
01673         if ( !strequal(hdr_ba->addr.str, pipe_names[pipe_idx].client_pipe) &&
01674              !strequal(hdr_ba->addr.str, pipe_names[pipe_idx].server_pipe) )
01675         {
01676                 DEBUG(4,("bind_rpc_pipe: pipe_name %s != expected pipe %s.  oh well!\n",
01677                          pipe_names[i].server_pipe ,hdr_ba->addr.str));
01678                 return False;
01679         }
01680         
01681         DEBUG(5,("bind_rpc_pipe: server pipe_name found: %s\n", pipe_names[i].server_pipe ));
01682 
01683         if (pipe_names[pipe_idx].server_pipe == NULL) {
01684                 DEBUG(2,("bind_rpc_pipe: pipe name %s unsupported\n", hdr_ba->addr.str));
01685                 return False;
01686         }
01687 #endif  /* JERRY */
01688 
01689         /* check the transfer syntax */
01690         if ((hdr_ba->transfer.version != transfer->version) ||
01691              (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
01692                 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
01693                 return False;
01694         }
01695 
01696         if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
01697                 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
01698                           hdr_ba->res.num_results, hdr_ba->res.reason));
01699         }
01700 
01701         DEBUG(5,("check_bind_response: accepted!\n"));
01702         return True;
01703 }

static NTSTATUS create_rpc_bind_auth3 ( struct rpc_pipe_client cli,
uint32  rpc_call_id,
enum pipe_auth_type  auth_type,
enum pipe_auth_level  auth_level,
DATA_BLOB pauth_blob,
prs_struct rpc_out 
) [static]

cli_pipe.c1712 行で定義されています。

参照先 data_blob_::datainit_rpc_hdr()init_rpc_hdr_auth()data_blob_::lengthmap_pipe_auth_type_to_rpc_auth_type()RPC_AUTH3smb_io_rpc_hdr()smb_io_rpc_hdr_auth().

参照元 rpc_finish_auth3_bind().

01718 {
01719         RPC_HDR hdr;
01720         RPC_HDR_AUTH hdr_auth;
01721         uint32 pad = 0;
01722 
01723         /* Create the request RPC_HDR */
01724         init_rpc_hdr(&hdr, RPC_AUTH3, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id,
01725                      RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
01726                      pauth_blob->length );
01727         
01728         /* Marshall it. */
01729         if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
01730                 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
01731                 return NT_STATUS_NO_MEMORY;
01732         }
01733 
01734         /*
01735                 I'm puzzled about this - seems to violate the DCE RPC auth rules,
01736                 about padding - shouldn't this pad to length 8 ? JRA.
01737         */
01738 
01739         /* 4 bytes padding. */
01740         if (!prs_uint32("pad", rpc_out, 0, &pad)) {
01741                 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
01742                 return NT_STATUS_NO_MEMORY;
01743         }
01744 
01745         /* Create the request RPC_HDR_AUTHA */
01746         init_rpc_hdr_auth(&hdr_auth,
01747                         map_pipe_auth_type_to_rpc_auth_type(auth_type),
01748                         auth_level, 0, 1);
01749 
01750         if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
01751                 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
01752                 return NT_STATUS_NO_MEMORY;
01753         }
01754 
01755         /*
01756          * Append the auth data to the outgoing buffer.
01757          */
01758 
01759         if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
01760                 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
01761                 return NT_STATUS_NO_MEMORY;
01762         }
01763 
01764         return NT_STATUS_OK;
01765 }

static NTSTATUS rpc_finish_auth3_bind ( struct rpc_pipe_client cli,
RPC_HDR phdr,
prs_struct rbuf,
uint32  rpc_call_id,
enum pipe_auth_type  auth_type,
enum pipe_auth_level  auth_level 
) [static]

cli_pipe.c1771 行で定義されています。

参照先 rpc_hdr_info::auth_lenclicli_get_nt_error()cli_write()create_rpc_bind_auth3()data_blob_::datadata_blob()data_blob_free()cli_state::desthostrpc_hdr_info::frag_lenntlmssp_update()prs_init()prs_mem_free()smb_io_rpc_hdr_auth().

参照元 rpc_pipe_bind().

01777 {
01778         DATA_BLOB server_response = data_blob(NULL,0);
01779         DATA_BLOB client_reply = data_blob(NULL,0);
01780         RPC_HDR_AUTH hdr_auth;
01781         NTSTATUS nt_status;
01782         prs_struct rpc_out;
01783         ssize_t ret;
01784 
01785         if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
01786                 return NT_STATUS_INVALID_PARAMETER;
01787         }
01788 
01789         /* Process the returned NTLMSSP blob first. */
01790         if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
01791                 return NT_STATUS_INVALID_PARAMETER;
01792         }
01793 
01794         if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
01795                 return NT_STATUS_INVALID_PARAMETER;
01796         }
01797 
01798         /* TODO - check auth_type/auth_level match. */
01799 
01800         server_response = data_blob(NULL, phdr->auth_len);
01801         prs_copy_data_out((char *)server_response.data, rbuf, phdr->auth_len);
01802         
01803         nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state,
01804                                    server_response,
01805                                    &client_reply);
01806         
01807         if (!NT_STATUS_IS_OK(nt_status)) {
01808                 DEBUG(0,("rpc_finish_auth3_bind: NTLMSSP update using server blob failed.\n"));
01809                 data_blob_free(&server_response);
01810                 return nt_status;
01811         }
01812 
01813         prs_init(&rpc_out, 0, prs_get_mem_context(rbuf), MARSHALL);
01814 
01815         nt_status = create_rpc_bind_auth3(cli, rpc_call_id,
01816                                 auth_type, auth_level,
01817                                 &client_reply, &rpc_out);
01818 
01819         if (!NT_STATUS_IS_OK(nt_status)) {
01820                 prs_mem_free(&rpc_out);
01821                 data_blob_free(&client_reply);
01822                 data_blob_free(&server_response);
01823                 return nt_status;
01824         }
01825 
01826         /* 8 here is named pipe message mode. */
01827         ret = cli_write(cli->cli, cli->fnum, 0x8, prs_data_p(&rpc_out), 0,
01828                                 (size_t)prs_offset(&rpc_out));
01829 
01830         if (ret != (ssize_t)prs_offset(&rpc_out)) {
01831                 DEBUG(0,("rpc_send_auth_auth3: cli_write failed. Return was %d\n", (int)ret));
01832                 prs_mem_free(&rpc_out);
01833                 data_blob_free(&client_reply);
01834                 data_blob_free(&server_response);
01835                 return cli_get_nt_error(cli->cli);
01836         }
01837 
01838         DEBUG(5,("rpc_send_auth_auth3: Remote machine %s pipe %s "
01839                 "fnum 0x%x sent auth3 response ok.\n",
01840                 cli->cli->desthost,
01841                 cli->pipe_name,
01842                 (unsigned int)cli->fnum));
01843 
01844         prs_mem_free(&rpc_out);
01845         data_blob_free(&client_reply);
01846         data_blob_free(&server_response);
01847         return NT_STATUS_OK;
01848 }

static NTSTATUS create_rpc_alter_context ( uint32  rpc_call_id,
RPC_IFACE abstract,
RPC_IFACE transfer,
enum pipe_auth_level  auth_level,
const DATA_BLOB pauth_blob,
prs_struct rpc_out 
) [static]

cli_pipe.c1855 行で定義されています。

参照先 create_bind_or_alt_ctx_internal()data_blob_::datainit_rpc_hdr_auth()data_blob_::lengthprs_init()prs_mem_free()RPC_ALTCONT.

参照元 rpc_finish_spnego_ntlmssp_bind().

01861 {
01862         RPC_HDR_AUTH hdr_auth;
01863         prs_struct auth_info;
01864         NTSTATUS ret = NT_STATUS_OK;
01865 
01866         ZERO_STRUCT(hdr_auth);
01867         prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL);
01868 
01869         /* We may change the pad length before marshalling. */
01870         init_rpc_hdr_auth(&hdr_auth, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
01871 
01872         if (pauth_blob->length) {
01873                 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
01874                         prs_mem_free(&auth_info);
01875                         return NT_STATUS_NO_MEMORY;
01876                 }
01877         }
01878 
01879         ret = create_bind_or_alt_ctx_internal(RPC_ALTCONT,
01880                                                 rpc_out, 
01881                                                 rpc_call_id,
01882                                                 abstract,
01883                                                 transfer,
01884                                                 &hdr_auth,
01885                                                 &auth_info);
01886         prs_mem_free(&auth_info);
01887         return ret;
01888 }

static NTSTATUS rpc_finish_spnego_ntlmssp_bind ( struct rpc_pipe_client cli,
RPC_HDR phdr,
prs_struct rbuf,
uint32  rpc_call_id,
RPC_IFACE abstract,
RPC_IFACE transfer,
enum pipe_auth_type  auth_type,
enum pipe_auth_level  auth_level 
) [static]

cli_pipe.c1895 行で定義されています。

参照先 rpc_hdr_info::auth_lenclicreate_rpc_alter_context()data_blob_::datadata_blob()data_blob_free()cli_state::desthostrpc_hdr_info::frag_lencli_state::mem_ctxntlmssp_update()prs_init()prs_mem_free()RPC_ALTCONTRESPrpc_api_pipe()smb_io_rpc_hdr()smb_io_rpc_hdr_auth()spnego_gen_auth()spnego_parse_auth_response()spnego_parse_challenge().

参照元 rpc_pipe_bind().

01903 {
01904         DATA_BLOB server_spnego_response = data_blob(NULL,0);
01905         DATA_BLOB server_ntlm_response = data_blob(NULL,0);
01906         DATA_BLOB client_reply = data_blob(NULL,0);
01907         DATA_BLOB tmp_blob = data_blob(NULL, 0);
01908         RPC_HDR_AUTH hdr_auth;
01909         NTSTATUS nt_status;
01910         prs_struct rpc_out;
01911 
01912         if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
01913                 return NT_STATUS_INVALID_PARAMETER;
01914         }
01915 
01916         /* Process the returned NTLMSSP blob first. */
01917         if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
01918                 return NT_STATUS_INVALID_PARAMETER;
01919         }
01920 
01921         if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
01922                 return NT_STATUS_INVALID_PARAMETER;
01923         }
01924 
01925         server_spnego_response = data_blob(NULL, phdr->auth_len);
01926         prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
01927         
01928         /* The server might give us back two challenges - tmp_blob is for the second. */
01929         if (!spnego_parse_challenge(server_spnego_response, &server_ntlm_response, &tmp_blob)) {
01930                 data_blob_free(&server_spnego_response);
01931                 data_blob_free(&server_ntlm_response);
01932                 data_blob_free(&tmp_blob);
01933                 return NT_STATUS_INVALID_PARAMETER;
01934         }
01935 
01936         /* We're finished with the server spnego response and the tmp_blob. */
01937         data_blob_free(&server_spnego_response);
01938         data_blob_free(&tmp_blob);
01939 
01940         nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state,
01941                                    server_ntlm_response,
01942                                    &client_reply);
01943         
01944         /* Finished with the server_ntlm response */
01945         data_blob_free(&server_ntlm_response);
01946 
01947         if (!NT_STATUS_IS_OK(nt_status)) {
01948                 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update using server blob failed.\n"));
01949                 data_blob_free(&client_reply);
01950                 return nt_status;
01951         }
01952 
01953         /* SPNEGO wrap the client reply. */
01954         tmp_blob = spnego_gen_auth(client_reply);
01955         data_blob_free(&client_reply);
01956         client_reply = tmp_blob;
01957         tmp_blob = data_blob(NULL,0); /* Ensure it's safe to free this just in case. */
01958 
01959         /* Now prepare the alter context pdu. */
01960         prs_init(&rpc_out, 0, prs_get_mem_context(rbuf), MARSHALL);
01961 
01962         nt_status = create_rpc_alter_context(rpc_call_id,
01963                                                 abstract,
01964                                                 transfer,
01965                                                 auth_level,
01966                                                 &client_reply,
01967                                                 &rpc_out);
01968 
01969         data_blob_free(&client_reply);
01970 
01971         if (!NT_STATUS_IS_OK(nt_status)) {
01972                 prs_mem_free(&rpc_out);
01973                 return nt_status;
01974         }
01975 
01976         /* Initialize the returning data struct. */
01977         prs_mem_free(rbuf);
01978         prs_init(rbuf, 0, cli->cli->mem_ctx, UNMARSHALL);
01979 
01980         nt_status = rpc_api_pipe(cli, &rpc_out, rbuf, RPC_ALTCONTRESP);
01981         if (!NT_STATUS_IS_OK(nt_status)) {
01982                 prs_mem_free(&rpc_out);
01983                 return nt_status;
01984         }
01985 
01986         prs_mem_free(&rpc_out);
01987 
01988         /* Get the auth blob from the reply. */
01989         if(!smb_io_rpc_hdr("rpc_hdr   ", phdr, rbuf, 0)) {
01990                 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: Failed to unmarshall RPC_HDR.\n"));
01991                 return NT_STATUS_BUFFER_TOO_SMALL;
01992         }
01993 
01994         if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
01995                 return NT_STATUS_INVALID_PARAMETER;
01996         }
01997 
01998         if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
01999                 return NT_STATUS_INVALID_PARAMETER;
02000         }
02001 
02002         server_spnego_response = data_blob(NULL, phdr->auth_len);
02003         prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
02004 
02005         /* Check we got a valid auth response. */
02006         if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK, &tmp_blob)) {
02007                 data_blob_free(&server_spnego_response);
02008                 data_blob_free(&tmp_blob);
02009                 return NT_STATUS_INVALID_PARAMETER;
02010         }
02011 
02012         data_blob_free(&server_spnego_response);
02013         data_blob_free(&tmp_blob);
02014 
02015         DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
02016                 "remote machine %s pipe %s fnum 0x%x.\n",
02017                 cli->cli->desthost,
02018                 cli->pipe_name,
02019                 (unsigned int)cli->fnum));
02020 
02021         return NT_STATUS_OK;
02022 }

static NTSTATUS rpc_pipe_bind ( struct rpc_pipe_client cli,
enum pipe_auth_type  auth_type,
enum pipe_auth_level  auth_level 
) [static]

cli_pipe.c2028 行で定義されています。

参照先 rpc_hdr_ba_info::bbacheck_bind_response()clicreate_rpc_bind_req()cli_state::desthostget_rpc_call_id()rpc_hdr_bba_info::max_rsizerpc_hdr_bba_info::max_tsizecli_state::mem_ctxPIPE_AUTH_LEVEL_INTEGRITYPIPE_AUTH_TYPE_KRB5PIPE_AUTH_TYPE_NONEPIPE_AUTH_TYPE_NTLMSSPPIPE_AUTH_TYPE_SCHANNELPIPE_AUTH_TYPE_SPNEGO_NTLMSSPprs_init()prs_mem_free()rpc_api_pipe()RPC_BINDACKrpc_finish_auth3_bind()rpc_finish_spnego_ntlmssp_bind()smb_io_rpc_hdr()smb_io_rpc_hdr_ba()statusvalid_pipe_name().

参照元 cli_rpc_pipe_open_krb5()cli_rpc_pipe_open_noauth()cli_rpc_pipe_open_ntlmssp_internal()cli_rpc_pipe_open_schannel_with_key().

02031 {
02032         RPC_HDR hdr;
02033         RPC_HDR_BA hdr_ba;
02034         RPC_IFACE abstract;
02035         RPC_IFACE transfer;
02036         prs_struct rpc_out;
02037         prs_struct rbuf;
02038         uint32 rpc_call_id;
02039         NTSTATUS status;
02040 
02041         DEBUG(5,("Bind RPC Pipe[%x]: %s auth_type %u, auth_level %u\n",
02042                 (unsigned int)cli->fnum,
02043                 cli->pipe_name,
02044                 (unsigned int)auth_type,
02045                 (unsigned int)auth_level ));
02046 
02047         if (!valid_pipe_name(cli->pipe_idx, &abstract, &transfer)) {
02048                 return NT_STATUS_INVALID_PARAMETER;
02049         }
02050 
02051         prs_init(&rpc_out, 0, cli->cli->mem_ctx, MARSHALL);
02052 
02053         rpc_call_id = get_rpc_call_id();
02054 
02055         /* Marshall the outgoing data. */
02056         status = create_rpc_bind_req(cli, &rpc_out, rpc_call_id,
02057                                 &abstract, &transfer,
02058                                 auth_type,
02059                                 auth_level);
02060 
02061         if (!NT_STATUS_IS_OK(status)) {
02062                 prs_mem_free(&rpc_out);
02063                 return status;
02064         }
02065 
02066         /* Initialize the incoming data struct. */
02067         prs_init(&rbuf, 0, cli->cli->mem_ctx, UNMARSHALL);
02068 
02069         /* send data on \PIPE\.  receive a response */
02070         status = rpc_api_pipe(cli, &rpc_out, &rbuf, RPC_BINDACK);
02071         if (!NT_STATUS_IS_OK(status)) {
02072                 prs_mem_free(&rpc_out);
02073                 return status;
02074         }
02075 
02076         prs_mem_free(&rpc_out);
02077 
02078         DEBUG(3,("rpc_pipe_bind: Remote machine %s pipe %s "
02079                 "fnum 0x%x bind request returned ok.\n",
02080                 cli->cli->desthost,
02081                 cli->pipe_name,
02082                 (unsigned int)cli->fnum));
02083 
02084         /* Unmarshall the RPC header */
02085         if(!smb_io_rpc_hdr("hdr"   , &hdr, &rbuf, 0)) {
02086                 DEBUG(0,("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
02087                 prs_mem_free(&rbuf);
02088                 return NT_STATUS_BUFFER_TOO_SMALL;
02089         }
02090 
02091         if(!smb_io_rpc_hdr_ba("", &hdr_ba, &rbuf, 0)) {
02092                 DEBUG(0,("rpc_pipe_bind: Failed to unmarshall RPC_HDR_BA.\n"));
02093                 prs_mem_free(&rbuf);
02094                 return NT_STATUS_BUFFER_TOO_SMALL;
02095         }
02096 
02097         if(!check_bind_response(&hdr_ba, cli->pipe_idx, &transfer)) {
02098                 DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n"));
02099                 prs_mem_free(&rbuf);
02100                 return NT_STATUS_BUFFER_TOO_SMALL;
02101         }
02102 
02103         cli->max_xmit_frag = hdr_ba.bba.max_tsize;
02104         cli->max_recv_frag = hdr_ba.bba.max_rsize;
02105 
02106         /* For authenticated binds we may need to do 3 or 4 leg binds. */
02107         switch(auth_type) {
02108 
02109                 case PIPE_AUTH_TYPE_NONE:
02110                 case PIPE_AUTH_TYPE_SCHANNEL:
02111                         /* Bind complete. */
02112                         break;
02113 
02114                 case PIPE_AUTH_TYPE_NTLMSSP:
02115                         /* Need to send AUTH3 packet - no reply. */
02116                         status = rpc_finish_auth3_bind(cli, &hdr, &rbuf, rpc_call_id,
02117                                                 auth_type, auth_level);
02118                         if (!NT_STATUS_IS_OK(status)) {
02119                                 prs_mem_free(&rbuf);
02120                                 return status;
02121                         }
02122                         break;
02123 
02124                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
02125                         /* Need to send alter context request and reply. */
02126                         status = rpc_finish_spnego_ntlmssp_bind(cli, &hdr, &rbuf, rpc_call_id,
02127                                                 &abstract, &transfer,
02128                                                 auth_type, auth_level);
02129                         if (!NT_STATUS_IS_OK(status)) {
02130                                 prs_mem_free(&rbuf);
02131                                 return status;
02132                         }
02133                         break;
02134 
02135                 case PIPE_AUTH_TYPE_KRB5:
02136                         /* */
02137 
02138                 default:
02139                         DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
02140                                 (unsigned int)auth_type ));
02141                         prs_mem_free(&rbuf);
02142                         return NT_STATUS_INVALID_INFO_CLASS;
02143         }
02144 
02145         /* For NTLMSSP ensure the server gave us the auth_level we wanted. */
02146         if (auth_type == PIPE_AUTH_TYPE_NTLMSSP || auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
02147                 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
02148                         if (!(cli->auth.a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
02149                                 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP signing and server refused.\n"));
02150                                 prs_mem_free(&rbuf);
02151                                 return NT_STATUS_INVALID_PARAMETER;
02152                         }
02153                 }
02154                 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
02155                         if (!(cli->auth.a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
02156                                 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP sealing and server refused.\n"));
02157                                 prs_mem_free(&rbuf);
02158                                 return NT_STATUS_INVALID_PARAMETER;
02159                         }
02160                 }
02161         }
02162 
02163         /* Pipe is bound - set up auth_type and auth_level data. */
02164 
02165         cli->auth.auth_type = auth_type;
02166         cli->auth.auth_level = auth_level;
02167 
02168         prs_mem_free(&rbuf);
02169         return NT_STATUS_OK;
02170 }

static struct rpc_pipe_client* cli_rpc_pipe_open ( struct cli_state cli,
int  pipe_idx,
NTSTATUS perr 
) [static]

cli_pipe.c2185 行で定義されています。

参照先 clicli_errstr()cli_get_nt_error()cli_get_pipe_name()cli_nt_create()cli_state::desthostrpc_pipe_client::fnumrpc_pipe_client::mem_ctxPIPE_AUTH_LEVEL_NONEPIPE_AUTH_TYPE_NONEcli_state::pipe_listresulttalloc_init().

参照元 cli_rpc_pipe_open_krb5()cli_rpc_pipe_open_noauth()cli_rpc_pipe_open_ntlmssp_internal()cli_rpc_pipe_open_schannel_with_key().

02186 {
02187         TALLOC_CTX *mem_ctx;
02188         struct rpc_pipe_client *result;
02189         int fnum;
02190 
02191         *perr = NT_STATUS_NO_MEMORY;
02192 
02193         /* sanity check to protect against crashes */
02194 
02195         if ( !cli ) {
02196                 *perr = NT_STATUS_INVALID_HANDLE;
02197                 return NULL;
02198         }
02199 
02200         /* The pipe name index must fall within our array */
02201         SMB_ASSERT((pipe_idx >= 0) && (pipe_idx < PI_MAX_PIPES));
02202 
02203         mem_ctx = talloc_init("struct rpc_pipe_client");
02204         if (mem_ctx == NULL) {
02205                 return NULL;
02206         }
02207 
02208         result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
02209         if (result == NULL) {
02210                 return NULL;
02211         }
02212 
02213         result->mem_ctx = mem_ctx;
02214 
02215         result->pipe_name = cli_get_pipe_name(pipe_idx);
02216 
02217         fnum = cli_nt_create(cli, result->pipe_name, DESIRED_ACCESS_PIPE);
02218 
02219         if (fnum == -1) {
02220                 DEBUG(1,("cli_rpc_pipe_open: cli_nt_create failed on pipe %s "
02221                          "to machine %s.  Error was %s\n",
02222                          result->pipe_name, cli->desthost,
02223                          cli_errstr(cli)));
02224                 *perr = cli_get_nt_error(cli);
02225                 talloc_destroy(result->mem_ctx);
02226                 return NULL;
02227         }
02228 
02229         result->fnum = fnum;
02230         result->cli = cli;
02231         result->pipe_idx = pipe_idx;
02232         result->auth.auth_type = PIPE_AUTH_TYPE_NONE;
02233         result->auth.auth_level = PIPE_AUTH_LEVEL_NONE;
02234 
02235         if (pipe_idx == PI_NETLOGON) {
02236                 /* Set up a netlogon credential chain for a netlogon pipe. */
02237                 result->dc = TALLOC_ZERO_P(mem_ctx, struct dcinfo);
02238                 if (result->dc == NULL) {
02239                         talloc_destroy(result->mem_ctx);
02240                         return NULL;
02241                 }
02242         }
02243 
02244         DLIST_ADD(cli->pipe_list, result);
02245         *perr = NT_STATUS_OK;
02246 
02247         return result;
02248 }

struct rpc_pipe_client* cli_rpc_pipe_open_noauth ( struct cli_state cli,
int  pipe_idx,
NTSTATUS perr 
)

cli_pipe.c2254 行で定義されています。

参照先 clicli_get_pipe_name()cli_rpc_pipe_close()cli_rpc_pipe_open()cli_state::desthostnt_errstr()PIPE_AUTH_LEVEL_NONEPIPE_AUTH_TYPE_NONEresultrpc_pipe_bind().

参照元 browse_host_rpc()cac_LsaOpenPolicy()cac_RegConnect()cac_SamConnect()cac_SamUserChangePasswd()cac_Shutdown()cac_SvcOpenScm()cacls_open_policy_hnd()change_trust_account_password()cli_open_policy_hnd()cm_connect_lsa()cm_connect_netlogon()cm_connect_sam()cmd_spoolss_printercmp()cmd_testme()connect_dst_pipe()connect_to_domain_password_server()create_cs()do_cmd()enumerate_domain_trusts()fetch_machine_sid()get_rpc_shares()get_schannel_session_key()get_sid_from_name()net_ads_printer_publish()net_get_remote_domain_sid()net_rpc_join_newstyle()net_rpc_lookup_name()net_sh_run()net_share_enum_rpc()netdom_get_domain_sid()netdom_join_domain()netdom_leave_domain()open_pipe_creds()remote_password_change()rpc_list_alias_members()rpc_oldjoin_internals()rpc_trustdom_establish()rpc_trustdom_list()rpc_trustdom_vampire()run_rpc_command()set_dc_type_and_flags()smbc_attr_server()spoolss_connect_to_client().

02255 {
02256         struct rpc_pipe_client *result;
02257 
02258         result = cli_rpc_pipe_open(cli, pipe_idx, perr);
02259         if (result == NULL) {
02260                 return NULL;
02261         }
02262 
02263         *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_NONE, PIPE_AUTH_LEVEL_NONE);
02264         if (!NT_STATUS_IS_OK(*perr)) {
02265                 int lvl = 0;
02266                 if (pipe_idx == PI_LSARPC_DS) {
02267                         /* non AD domains just don't have this pipe, avoid
02268                          * level 0 statement in that case - gd */
02269                         lvl = 3;
02270                 }
02271                 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe %s failed with error %s\n",
02272                         cli_get_pipe_name(pipe_idx), nt_errstr(*perr) ));
02273                 cli_rpc_pipe_close(result);
02274                 return NULL;
02275         }
02276 
02277         DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine %s and bound anonymously.\n",
02278                         result->pipe_name, cli->desthost ));
02279 
02280         return result;
02281 }

static void cli_ntlmssp_auth_free ( struct cli_pipe_auth_data auth  )  [static]

cli_pipe.c2287 行で定義されています。

参照先 cli_pipe_auth_data::a_urpc_pipe_client::authntlmssp_end()cli_pipe_auth_data::ntlmssp_state.

参照元 cli_rpc_pipe_open_ntlmssp_internal().

02288 {
02289         if (auth->a_u.ntlmssp_state) {
02290                 ntlmssp_end(&auth->a_u.ntlmssp_state);
02291                 auth->a_u.ntlmssp_state = NULL;
02292         }
02293 }

static struct rpc_pipe_client* cli_rpc_pipe_open_ntlmssp_internal ( struct cli_state cli,
int  pipe_idx,
enum pipe_auth_type  auth_type,
enum pipe_auth_level  auth_level,
const char *  domain,
const char *  username,
const char *  password,
NTSTATUS perr 
) [static]

cli_pipe.c2299 行で定義されています。

参照先 clicli_ntlmssp_auth_free()cli_rpc_pipe_close()cli_rpc_pipe_open()cli_state::desthostcli_state::domainerrntlmssp_state::neg_flagsnt_errstr()ntlmssp_client_start()ntlmssp_set_domain()ntlmssp_set_password()ntlmssp_set_username()pwd_info::null_pwdPIPE_AUTH_LEVEL_INTEGRITYPIPE_AUTH_LEVEL_PRIVACYcli_state::pwdpwd_set_cleartext()resultrpc_pipe_bind()cli_state::user_name.

参照元 cli_rpc_pipe_open_ntlmssp()cli_rpc_pipe_open_spnego_ntlmssp().

02307 {
02308         struct rpc_pipe_client *result;
02309         NTLMSSP_STATE *ntlmssp_state = NULL;
02310 
02311         result = cli_rpc_pipe_open(cli, pipe_idx, perr);
02312         if (result == NULL) {
02313                 return NULL;
02314         }
02315         
02316         result->auth.cli_auth_data_free_func = cli_ntlmssp_auth_free;
02317 
02318         result->domain = domain;
02319         result->user_name = username;
02320         pwd_set_cleartext(&result->pwd, password);
02321 
02322         *perr = ntlmssp_client_start(&ntlmssp_state);
02323         if (!NT_STATUS_IS_OK(*perr)) {
02324                 goto err;
02325         }
02326 
02327         result->auth.a_u.ntlmssp_state = ntlmssp_state;
02328 
02329         *perr = ntlmssp_set_username(ntlmssp_state, cli->user_name);
02330         if (!NT_STATUS_IS_OK(*perr)) {
02331                 goto err;
02332         }
02333 
02334         *perr = ntlmssp_set_domain(ntlmssp_state, cli->domain); 
02335         if (!NT_STATUS_IS_OK(*perr)) {
02336                 goto err;
02337         }
02338 
02339         if (cli->pwd.null_pwd) {
02340                 *perr = ntlmssp_set_password(ntlmssp_state, NULL);
02341                 if (!NT_STATUS_IS_OK(*perr)) {
02342                         goto err;
02343                 }
02344         } else {
02345                 *perr = ntlmssp_set_password(ntlmssp_state, password);
02346                 if (!NT_STATUS_IS_OK(*perr)) {
02347                         goto err;
02348                 }
02349         }
02350 
02351         /* Turn off sign+seal to allow selected auth level to turn it back on. */
02352         ntlmssp_state->neg_flags &= ~(NTLMSSP_NEGOTIATE_SIGN|NTLMSSP_NEGOTIATE_SEAL);
02353 
02354         if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
02355                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
02356         } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
02357                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
02358         }
02359         
02360         *perr = rpc_pipe_bind(result, auth_type, auth_level);
02361         if (!NT_STATUS_IS_OK(*perr)) {
02362                 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
02363                         nt_errstr(*perr) ));
02364                 goto err;
02365         }
02366 
02367         DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
02368                 "machine %s and bound NTLMSSP as user %s\\%s.\n",
02369                 result->pipe_name, cli->desthost,
02370                 domain, username ));
02371 
02372         return result;
02373 
02374   err:
02375 
02376         cli_rpc_pipe_close(result);
02377         return NULL;
02378 }

struct rpc_pipe_client* cli_rpc_pipe_open_ntlmssp ( struct cli_state cli,
int  pipe_idx,
enum pipe_auth_level  auth_level,
const char *  domain,
const char *  username,
const char *  password,
NTSTATUS perr 
)

cli_pipe.c2385 行で定義されています。

参照先 clicli_rpc_pipe_open_ntlmssp_internal()PIPE_AUTH_TYPE_NTLMSSP.

参照元 do_cmd()remote_password_change().

02392 {
02393         return cli_rpc_pipe_open_ntlmssp_internal(cli,
02394                                                 pipe_idx,
02395                                                 PIPE_AUTH_TYPE_NTLMSSP,
02396                                                 auth_level,
02397                                                 domain,
02398                                                 username,
02399                                                 password,
02400                                                 perr);
02401 }

struct rpc_pipe_client* cli_rpc_pipe_open_spnego_ntlmssp ( struct cli_state cli,
int  pipe_idx,
enum pipe_auth_level  auth_level,
const char *  domain,
const char *  username,
const char *  password,
NTSTATUS perr 
)

cli_pipe.c2408 行で定義されています。

参照先 clicli_rpc_pipe_open_ntlmssp_internal()PIPE_AUTH_TYPE_SPNEGO_NTLMSSP.

参照元 cm_connect_lsa()cm_connect_sam()do_cmd()get_schannel_session_key_auth_ntlmssp().

02415 {
02416         return cli_rpc_pipe_open_ntlmssp_internal(cli,
02417                                                 pipe_idx,
02418                                                 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
02419                                                 auth_level,
02420                                                 domain,
02421                                                 username,
02422                                                 password,
02423                                                 perr);
02424 }

static BOOL get_schannel_session_key_common ( struct rpc_pipe_client netlogon_pipe,
struct cli_state cli,
const char *  domain,
uint32 *  pneg_flags,
NTSTATUS perr 
) [static]

cli_pipe.c2429 行で定義されています。

参照先 clicli_state::desthostget_trust_pw_hash()global_mynament_errstr()rpccli_netlogon_setup_creds().

参照元 get_schannel_session_key()get_schannel_session_key_auth_ntlmssp().

02434 {
02435         uint32 sec_chan_type = 0;
02436         unsigned char machine_pwd[16];
02437         const char *machine_account;
02438 
02439         /* Get the machine account credentials from secrets.tdb. */
02440         if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
02441                                &sec_chan_type))
02442         {
02443                 DEBUG(0, ("get_schannel_session_key: could not fetch "
02444                         "trust account password for domain '%s'\n",
02445                         domain));
02446                 *perr = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
02447                 return False;
02448         }
02449 
02450         *perr = rpccli_netlogon_setup_creds(netlogon_pipe,
02451                                         cli->desthost, /* server name */
02452                                         domain,        /* domain */
02453                                         global_myname(), /* client name */
02454                                         machine_account, /* machine account name */
02455                                         machine_pwd,
02456                                         sec_chan_type,
02457                                         pneg_flags);
02458 
02459         if (!NT_STATUS_IS_OK(*perr)) {
02460                 DEBUG(3,("get_schannel_session_key_common: rpccli_netlogon_setup_creds "
02461                         "failed with result %s to server %s, domain %s, machine account %s.\n",
02462                         nt_errstr(*perr), cli->desthost, domain, machine_account ));
02463                 return False;
02464         }
02465 
02466         if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
02467                 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
02468                         cli->desthost));
02469                 *perr = NT_STATUS_INVALID_NETWORK_RESPONSE;
02470                 return False;
02471         }
02472 
02473         return True;
02474 }

struct rpc_pipe_client* get_schannel_session_key ( struct cli_state cli,
const char *  domain,
uint32 *  pneg_flags,
NTSTATUS perr 
)

cli_pipe.c2482 行で定義されています。

参照先 clicli_rpc_pipe_close()cli_rpc_pipe_open_noauth()get_schannel_session_key_common().

参照元 cli_rpc_pipe_open_schannel()net_rpc_join_ok().

02486 {
02487         struct rpc_pipe_client *netlogon_pipe = NULL;
02488 
02489         netlogon_pipe = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, perr);
02490         if (!netlogon_pipe) {
02491                 return NULL;
02492         }
02493 
02494         if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
02495                                              pneg_flags, perr))
02496         {
02497                 cli_rpc_pipe_close(netlogon_pipe);
02498                 return NULL;
02499         }
02500 
02501         return netlogon_pipe;
02502 }

struct rpc_pipe_client* cli_rpc_pipe_open_schannel_with_key ( struct cli_state cli,
int  pipe_idx,
enum pipe_auth_level  auth_level,
const char *  domain,
const struct dcinfo pdc,
NTSTATUS perr 
)

cli_pipe.c2510 行で定義されています。

参照先 clicli_rpc_pipe_close()cli_rpc_pipe_open()cli_state::desthostnt_errstr()PIPE_AUTH_TYPE_SCHANNELresultrpc_pipe_bind()dcinfo::sess_key.

参照元 cli_rpc_pipe_open_ntlmssp_auth_schannel()cli_rpc_pipe_open_schannel()cm_connect_lsa()cm_connect_netlogon()cm_connect_sam()net_rpc_join_newstyle()net_rpc_join_ok().

02516 {
02517         struct rpc_pipe_client *result;
02518 
02519         result = cli_rpc_pipe_open(cli, pipe_idx, perr);
02520         if (result == NULL) {
02521                 return NULL;
02522         }
02523 
02524         result->auth.a_u.schannel_auth = TALLOC_ZERO_P(result->mem_ctx, struct schannel_auth_struct);
02525         if (!result->auth.a_u.schannel_auth) {
02526                 cli_rpc_pipe_close(result);
02527                 *perr = NT_STATUS_NO_MEMORY;
02528                 return NULL;
02529         }
02530 
02531         result->domain = domain;
02532         memcpy(result->auth.a_u.schannel_auth->sess_key, pdc->sess_key, 16);
02533 
02534         *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_SCHANNEL, auth_level);
02535         if (!NT_STATUS_IS_OK(*perr)) {
02536                 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: cli_rpc_pipe_bind failed with error %s\n",
02537                         nt_errstr(*perr) ));
02538                 cli_rpc_pipe_close(result);
02539                 return NULL;
02540         }
02541 
02542         /* The credentials on a new netlogon pipe are the ones we are passed in - copy them over. */
02543         if (result->dc) {
02544                 *result->dc = *pdc;
02545         }
02546 
02547         DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
02548                 "for domain %s "
02549                 "and bound using schannel.\n",
02550                 result->pipe_name, cli->desthost, domain ));
02551 
02552         return result;
02553 }

static struct rpc_pipe_client* get_schannel_session_key_auth_ntlmssp ( struct cli_state cli,
const char *  domain,
const char *  username,
const char *  password,
uint32 *  pneg_flags,
NTSTATUS perr 
) [static]

cli_pipe.c2561 行で定義されています。

参照先 clicli_rpc_pipe_close()cli_rpc_pipe_open_spnego_ntlmssp()get_schannel_session_key_common()PIPE_AUTH_LEVEL_PRIVACY.

参照元 cli_rpc_pipe_open_ntlmssp_auth_schannel().

02567 {
02568         struct rpc_pipe_client *netlogon_pipe = NULL;
02569 
02570         netlogon_pipe = cli_rpc_pipe_open_spnego_ntlmssp(cli, PI_NETLOGON, PIPE_AUTH_LEVEL_PRIVACY, domain, username, password, perr);
02571         if (!netlogon_pipe) {
02572                 return NULL;
02573         }
02574 
02575         if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
02576                                              pneg_flags, perr))
02577         {
02578                 cli_rpc_pipe_close(netlogon_pipe);
02579                 return NULL;
02580         }
02581 
02582         return netlogon_pipe;
02583 }

struct rpc_pipe_client* cli_rpc_pipe_open_ntlmssp_auth_schannel ( struct cli_state cli,
int  pipe_idx,
enum pipe_auth_level  auth_level,
const char *  domain,
const char *  username,
const char *  password,
NTSTATUS perr 
)

cli_pipe.c2591 行で定義されています。

参照先 clicli_rpc_pipe_close()cli_rpc_pipe_open_schannel_with_key()rpc_pipe_client::dccli_state::desthostget_schannel_session_key_auth_ntlmssp()result.

02598 {
02599         uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
02600         struct rpc_pipe_client *netlogon_pipe = NULL;
02601         struct rpc_pipe_client *result = NULL;
02602 
02603         netlogon_pipe = get_schannel_session_key_auth_ntlmssp(cli, domain, username,
02604                                                         password, &neg_flags, perr);
02605         if (!netlogon_pipe) {
02606                 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
02607                         "key from server %s for domain %s.\n",
02608                         cli->desthost, domain ));
02609                 return NULL;
02610         }
02611 
02612         result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
02613                                 auth_level,
02614                                 domain, netlogon_pipe->dc, perr);
02615 
02616         /* Now we've bound using the session key we can close the netlog pipe. */
02617         cli_rpc_pipe_close(netlogon_pipe);
02618 
02619         return result;
02620 }

struct rpc_pipe_client* cli_rpc_pipe_open_schannel ( struct cli_state cli,
int  pipe_idx,
enum pipe_auth_level  auth_level,
const char *  domain,
NTSTATUS perr 
)

cli_pipe.c2627 行で定義されています。

参照先 clicli_rpc_pipe_close()cli_rpc_pipe_open_schannel_with_key()rpc_pipe_client::dccli_state::desthostget_schannel_session_key()result.

参照元 connect_to_domain_password_server()do_cmd()run_rpc_command().

02632 {
02633         uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
02634         struct rpc_pipe_client *netlogon_pipe = NULL;
02635         struct rpc_pipe_client *result = NULL;
02636 
02637         netlogon_pipe = get_schannel_session_key(cli, domain, &neg_flags, perr);
02638         if (!netlogon_pipe) {
02639                 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
02640                         "key from server %s for domain %s.\n",
02641                         cli->desthost, domain ));
02642                 return NULL;
02643         }
02644 
02645         result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
02646                                 auth_level,
02647                                 domain, netlogon_pipe->dc, perr);
02648 
02649         /* Now we've bound using the session key we can close the netlog pipe. */
02650         cli_rpc_pipe_close(netlogon_pipe);
02651 
02652         return result;
02653 }

static void kerberos_auth_struct_free ( struct cli_pipe_auth_data a  )  [static]

cli_pipe.c2661 行で定義されています。

参照先 cli_pipe_auth_data::a_udata_blob_free()cli_pipe_auth_data::kerberos_authkerberos_auth_struct::session_key.

参照元 cli_rpc_pipe_open_krb5().

02662 {
02663         data_blob_free(&a->a_u.kerberos_auth->session_key);
02664 }

struct rpc_pipe_client* cli_rpc_pipe_open_krb5 ( struct cli_state cli,
int  pipe_idx,
enum pipe_auth_level  auth_level,
const char *  service_princ,
const char *  username,
const char *  password,
NTSTATUS perr 
)

cli_pipe.c2674 行で定義されています。

参照先 clicli_rpc_pipe_close()cli_rpc_pipe_open()cli_state::desthostkerberos_auth_struct_free()kerberos_kinit_password()cli_state::mem_ctxnt_errstr()PIPE_AUTH_TYPE_KRB5resultrpc_pipe_bind()talloc_asprintf().

02681 {
02682 #ifdef HAVE_KRB5
02683         struct rpc_pipe_client *result;
02684 
02685         result = cli_rpc_pipe_open(cli, pipe_idx, perr);
02686         if (result == NULL) {
02687                 return NULL;
02688         }
02689 
02690         /* Default service principal is "desthost$@realm" */
02691         if (!service_princ) {
02692                 service_princ = talloc_asprintf(result->mem_ctx, "%s$@%s",
02693                         cli->desthost, lp_realm() );
02694                 if (!service_princ) {
02695                         cli_rpc_pipe_close(result);
02696                         return NULL;
02697                 }
02698         }
02699 
02700         /* Only get a new TGT if username/password are given. */
02701         if (username && password) {
02702                 int ret = kerberos_kinit_password(username, password, 0, NULL);
02703                 if (ret) {
02704                         cli_rpc_pipe_close(result);
02705                         return NULL;
02706                 }
02707         }
02708 
02709         result->auth.a_u.kerberos_auth = TALLOC_ZERO_P(cli->mem_ctx, struct kerberos_auth_struct);
02710         if (!result->auth.a_u.kerberos_auth) {
02711                 cli_rpc_pipe_close(result);
02712                 *perr = NT_STATUS_NO_MEMORY;
02713                 return NULL;
02714         }
02715 
02716         result->auth.a_u.kerberos_auth->service_principal = service_princ;
02717         result->auth.cli_auth_data_free_func = kerberos_auth_struct_free;
02718 
02719         *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_KRB5, auth_level);
02720         if (!NT_STATUS_IS_OK(*perr)) {
02721                 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed with error %s\n",
02722                         nt_errstr(*perr) ));
02723                 cli_rpc_pipe_close(result);
02724                 return NULL;
02725         }
02726 
02727         return result;
02728 #else
02729         DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
02730         return NULL;
02731 #endif
02732 }

void cli_rpc_pipe_close ( struct rpc_pipe_client cli  ) 

cli_pipe.c2740 行で定義されています。

参照先 clicli_close()cli_errstr()cli_state::desthostcli_state::mem_ctxcli_state::pipe_list.

02741 {
02742         if (!cli_close(cli->cli, cli->fnum)) {
02743                 DEBUG(0,("cli_rpc_pipe_close: cli_close failed on pipe %s "
02744                          "to machine %s.  Error was %s\n",
02745                          cli->pipe_name),
02746                          cli->cli->desthost,
02747                          cli_errstr(cli->cli)));
02748         }
02749 
02750         if (cli->auth.cli_auth_data_free_func) {
02751                 (*cli->auth.cli_auth_data_free_func)(&cli->auth);
02752         }
02753         DEBUG(10,("cli_rpc_pipe_close: closed pipe %s to machine %s\n",
02754                 cli->pipe_name, cli->cli->desthost ));
02755 
02756         DLIST_REMOVE(cli->cli->pipe_list, cli);
02757         talloc_destroy(cli->mem_ctx);   
02758 }


変数

struct pipe_id_info pipe_names[]

parse_rpc.c209 行で定義されています。

参照元 check_bind_req()check_bind_response()cli_get_pipe_name()reply_open_pipe_and_X()valid_pipe_name().


Sambaに対してSat Aug 29 21:24:06 2009に生成されました。  doxygen 1.4.7