関数 | |
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_client * | cli_rpc_pipe_open (struct cli_state *cli, int pipe_idx, NTSTATUS *perr) |
rpc_pipe_client * | cli_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_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) |
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) |
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) |
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_client * | get_schannel_session_key (struct cli_state *cli, const char *domain, uint32 *pneg_flags, NTSTATUS *perr) |
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) |
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) |
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) |
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) |
static void | kerberos_auth_struct_free (struct cli_pipe_auth_data *a) |
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) |
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.c の 32 行で定義されています。
参照先 PIPE_AUTH_TYPE_KRB5・PIPE_AUTH_TYPE_NONE・PIPE_AUTH_TYPE_NTLMSSP・PIPE_AUTH_TYPE_SCHANNEL・PIPE_AUTH_TYPE_SPNEGO_KRB5・PIPE_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] |
static NTSTATUS rpc_read | ( | struct rpc_pipe_client * | cli, | |
prs_struct * | current_pdu, | |||
uint32 | data_to_read, | |||
uint32 * | current_pdu_offset | |||
) | [static] |
cli_pipe.c の 76 行で定義されています。
参照先 cli・cli_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.c の 169 行で定義されています。
参照先 cli・rpc_hdr_info::frag_len・rpc_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, ¤t_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, ¤t_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.c の 212 行で定義されています。
参照先 rpc_hdr_info::auth_len・rpc_hdr_auth_info::auth_pad_len・cli・data_blob_::data・cli_state::desthost・rpc_hdr_info::frag_len・data_blob_::length・nt_errstr()・ntlmssp_check_packet()・ntlmssp_unseal_packet()・PIPE_AUTH_LEVEL_CONNECT・PIPE_AUTH_LEVEL_INTEGRITY・PIPE_AUTH_LEVEL_NONE・PIPE_AUTH_LEVEL_PRIVACY・smb_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.c の 338 行で定義されています。
参照先 rpc_hdr_info::auth_len・rpc_hdr_auth_info::auth_pad_len・rpc_hdr_auth_info::auth_type・cli・cli_state::desthost・rpc_hdr_info::frag_len・PIPE_AUTH_LEVEL_CONNECT・PIPE_AUTH_LEVEL_NONE・SENDER_IS_ACCEPTOR・schannel_auth_struct::seq_num・smb_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.c の 437 行で定義されています。
参照先 rpc_hdr_info::auth_len・cli・cli_pipe_verify_ntlmssp()・cli_pipe_verify_schannel()・cli_state::desthost・rpc_hdr_info::frag_len・PIPE_AUTH_TYPE_KRB5・PIPE_AUTH_TYPE_NONE・PIPE_AUTH_TYPE_NTLMSSP・PIPE_AUTH_TYPE_SCHANNEL・PIPE_AUTH_TYPE_SPNEGO_KRB5・PIPE_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.c の 507 行で定義されています。
参照先 rpc_hdr_resp_info::alloc_hint・rpc_hdr_info::auth_len・cli・cli_pipe_validate_rpc_response()・dcerpc_errstr()・cli_state::desthost・rpc_hdr_info::flags・rpc_hdr_info::frag_len・rpc_hdr_info::pkt_type・RPC_ALTCONTRESP・RPC_BINDACK・RPC_BINDNACK・RPC_FAULT・RPC_RESPONSE・smb_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.c の 676 行で定義されています。
参照先 rpc_hdr_info::frag_len・prs_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.c の 738 行で定義されています。
参照先 _prs_struct::bigendian_data・cli・cli_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::desthost・err・rpc_hdr_info::flags・rpc_hdr_info::pack_type・prs_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(¤t_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(¤t_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(¤t_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, ¤t_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, ¤t_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(¤t_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, ¤t_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(¤t_pdu); 00897 return NT_STATUS_OK; 00898 00899 err: 00900 00901 prs_mem_free(¤t_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.c の 910 行で定義されています。
参照先 cli・cli_krb5_get_ticket()・data_blob_::data・data_blob()・data_blob_free()・dump_data()・init_rpc_hdr_auth()・data_blob_::length・prs_mem_free()・kerberos_auth_struct::service_principal・kerberos_auth_struct::session_key・spnego_gen_krb5_wrap().
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.c の 969 行で定義されています。
参照先 cli・data_blob_::data・data_blob()・data_blob_free()・dump_data()・gen_negTokenInit()・init_rpc_hdr_auth()・data_blob_::length・ntlmssp_update()・prs_mem_free().
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.c の 1016 行で定義されています。
参照先 cli・data_blob_::data・data_blob()・data_blob_free()・dump_data()・init_rpc_hdr_auth()・data_blob_::length・ntlmssp_update()・prs_mem_free().
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.c の 1057 行で定義されています。
参照先 cli・cli_state::domain・global_myname・init_rpc_auth_schannel_neg()・init_rpc_hdr_auth()・lp_workgroup()・prs_mem_free()・smb_io_rpc_auth_schannel_neg().
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.c の 1093 行で定義されています。
参照先 rpc_hdr_auth_info::auth_pad_len・init_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.c の 1175 行で定義されています。
参照先 cli・create_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_KRB5・PIPE_AUTH_TYPE_NONE・PIPE_AUTH_TYPE_NTLMSSP・PIPE_AUTH_TYPE_SCHANNEL・PIPE_AUTH_TYPE_SPNEGO_NTLMSSP・prs_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.c の 1246 行で定義されています。
参照先 cli・data_blob_::data・data_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_INTEGRITY・PIPE_AUTH_LEVEL_PRIVACY・smb_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.c の 1326 行で定義されています。
参照先 cli・init_rpc_hdr_auth()・map_pipe_auth_type_to_rpc_auth_type()・PIPE_AUTH_LEVEL_INTEGRITY・PIPE_AUTH_LEVEL_PRIVACY・SENDER_IS_INITIATOR・schannel_auth_struct::seq_num・smb_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.c の 1391 行で定義されています。
参照先 cli・PIPE_AUTH_LEVEL_CONNECT・PIPE_AUTH_LEVEL_INTEGRITY・PIPE_AUTH_LEVEL_NONE・PIPE_AUTH_LEVEL_PRIVACY・PIPE_AUTH_TYPE_NTLMSSP・PIPE_AUTH_TYPE_SCHANNEL・PIPE_AUTH_TYPE_SPNEGO_NTLMSSP・smb_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.c の 1451 行で定義されています。
参照先 add_ntlmssp_auth_footer()・add_schannel_auth_footer()・calculate_data_len_tosend()・cli・cli_get_nt_error()・cli_write()・DEBUGLEVEL・dyn_LOGFILEBASE・flags・rpc_hdr_info::frag_len・get_rpc_call_id()・init_rpc_hdr()・init_rpc_hdr_req()・PIPE_AUTH_TYPE_NONE・PIPE_AUTH_TYPE_NTLMSSP・PIPE_AUTH_TYPE_SCHANNEL・PIPE_AUTH_TYPE_SPNEGO_NTLMSSP・prs_dump()・prs_init()・prs_mem_free()・rpc_api_pipe()・RPC_REQUEST・RPC_RESPONSE・smb_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.c の 1593 行で定義されています。
参照先 cli・cli_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.c の 1639 行で定義されています。
参照先 pipe_id_info::abstr_syntax・dump_data()・pipe_names・pipe_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.c の 1666 行で定義されています。
参照先 rpc_hdr_ba_info::addr・pipe_id_info::client_pipe・rpc_addr_info::len・rpc_results_info::num_results・pipe_names・rpc_results_info::reason・rpc_hdr_ba_info::res・rpc_results_info::result・pipe_id_info::server_pipe・rpc_addr_info::str・strequal()・rpc_hdr_ba_info::transfer・rpc_iface_info::uuid・rpc_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.c の 1712 行で定義されています。
参照先 data_blob_::data・init_rpc_hdr()・init_rpc_hdr_auth()・data_blob_::length・map_pipe_auth_type_to_rpc_auth_type()・RPC_AUTH3・smb_io_rpc_hdr()・smb_io_rpc_hdr_auth().
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.c の 1771 行で定義されています。
参照先 rpc_hdr_info::auth_len・cli・cli_get_nt_error()・cli_write()・create_rpc_bind_auth3()・data_blob_::data・data_blob()・data_blob_free()・cli_state::desthost・rpc_hdr_info::frag_len・ntlmssp_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.c の 1855 行で定義されています。
参照先 create_bind_or_alt_ctx_internal()・data_blob_::data・init_rpc_hdr_auth()・data_blob_::length・prs_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.c の 1895 行で定義されています。
参照先 rpc_hdr_info::auth_len・cli・create_rpc_alter_context()・data_blob_::data・data_blob()・data_blob_free()・cli_state::desthost・rpc_hdr_info::frag_len・cli_state::mem_ctx・ntlmssp_update()・prs_init()・prs_mem_free()・RPC_ALTCONTRESP・rpc_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.c の 2028 行で定義されています。
参照先 rpc_hdr_ba_info::bba・check_bind_response()・cli・create_rpc_bind_req()・cli_state::desthost・get_rpc_call_id()・rpc_hdr_bba_info::max_rsize・rpc_hdr_bba_info::max_tsize・cli_state::mem_ctx・PIPE_AUTH_LEVEL_INTEGRITY・PIPE_AUTH_TYPE_KRB5・PIPE_AUTH_TYPE_NONE・PIPE_AUTH_TYPE_NTLMSSP・PIPE_AUTH_TYPE_SCHANNEL・PIPE_AUTH_TYPE_SPNEGO_NTLMSSP・prs_init()・prs_mem_free()・rpc_api_pipe()・RPC_BINDACK・rpc_finish_auth3_bind()・rpc_finish_spnego_ntlmssp_bind()・smb_io_rpc_hdr()・smb_io_rpc_hdr_ba()・status・valid_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.c の 2185 行で定義されています。
参照先 cli・cli_errstr()・cli_get_nt_error()・cli_get_pipe_name()・cli_nt_create()・cli_state::desthost・rpc_pipe_client::fnum・rpc_pipe_client::mem_ctx・PIPE_AUTH_LEVEL_NONE・PIPE_AUTH_TYPE_NONE・cli_state::pipe_list・result・talloc_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.c の 2254 行で定義されています。
参照先 cli・cli_get_pipe_name()・cli_rpc_pipe_close()・cli_rpc_pipe_open()・cli_state::desthost・nt_errstr()・PIPE_AUTH_LEVEL_NONE・PIPE_AUTH_TYPE_NONE・result・rpc_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.c の 2287 行で定義されています。
参照先 cli_pipe_auth_data::a_u・rpc_pipe_client::auth・ntlmssp_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.c の 2299 行で定義されています。
参照先 cli・cli_ntlmssp_auth_free()・cli_rpc_pipe_close()・cli_rpc_pipe_open()・cli_state::desthost・cli_state::domain・err・ntlmssp_state::neg_flags・nt_errstr()・ntlmssp_client_start()・ntlmssp_set_domain()・ntlmssp_set_password()・ntlmssp_set_username()・pwd_info::null_pwd・PIPE_AUTH_LEVEL_INTEGRITY・PIPE_AUTH_LEVEL_PRIVACY・cli_state::pwd・pwd_set_cleartext()・result・rpc_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.c の 2385 行で定義されています。
参照先 cli・cli_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.c の 2408 行で定義されています。
参照先 cli・cli_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.c の 2429 行で定義されています。
参照先 cli・cli_state::desthost・get_trust_pw_hash()・global_myname・nt_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.c の 2482 行で定義されています。
参照先 cli・cli_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.c の 2510 行で定義されています。
参照先 cli・cli_rpc_pipe_close()・cli_rpc_pipe_open()・cli_state::desthost・nt_errstr()・PIPE_AUTH_TYPE_SCHANNEL・result・rpc_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.c の 2561 行で定義されています。
参照先 cli・cli_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.c の 2591 行で定義されています。
参照先 cli・cli_rpc_pipe_close()・cli_rpc_pipe_open_schannel_with_key()・rpc_pipe_client::dc・cli_state::desthost・get_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.c の 2627 行で定義されています。
参照先 cli・cli_rpc_pipe_close()・cli_rpc_pipe_open_schannel_with_key()・rpc_pipe_client::dc・cli_state::desthost・get_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.c の 2661 行で定義されています。
参照先 cli_pipe_auth_data::a_u・data_blob_free()・cli_pipe_auth_data::kerberos_auth・kerberos_auth_struct::session_key.
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.c の 2674 行で定義されています。
参照先 cli・cli_rpc_pipe_close()・cli_rpc_pipe_open()・cli_state::desthost・kerberos_auth_struct_free()・kerberos_kinit_password()・cli_state::mem_ctx・nt_errstr()・PIPE_AUTH_TYPE_KRB5・result・rpc_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.c の 2740 行で定義されています。
参照先 cli・cli_close()・cli_errstr()・cli_state::desthost・cli_state::mem_ctx・cli_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[] |