📄 srv_pipe.c
字号:
DEBUG(0,("pipe_ntlmssp_auth_bind: auth_ntlmssp_update failed: %s\n", nt_errstr(status) )); goto err; } data_blob_free(&blob); /* Copy the blob into the pout_auth parse struct */ init_rpc_hdr_auth(&auth_info, RPC_NTLMSSP_AUTH_TYPE, pauth_info->auth_level, RPC_HDR_AUTH_LEN, 1); if(!smb_io_rpc_hdr_auth("", &auth_info, pout_auth, 0)) { DEBUG(0,("pipe_ntlmssp_auth_bind: marshalling of RPC_HDR_AUTH failed.\n")); goto err; } if (!prs_copy_data_in(pout_auth, (char *)response.data, response.length)) { DEBUG(0,("pipe_ntlmssp_auth_bind: marshalling of data blob failed.\n")); goto err; } p->auth.a_u.auth_ntlmssp_state = a; p->auth.auth_data_free_func = &free_pipe_ntlmssp_auth_data; p->auth.auth_type = PIPE_AUTH_TYPE_NTLMSSP; data_blob_free(&blob); data_blob_free(&response); DEBUG(10,("pipe_ntlmssp_auth_bind: NTLMSSP auth started\n")); /* We can't set pipe_bound True yet - we need an RPC_AUTH3 response packet... */ return True; err: data_blob_free(&blob); data_blob_free(&response); free_pipe_ntlmssp_auth_data(&p->auth); p->auth.a_u.auth_ntlmssp_state = NULL; return False;}/******************************************************************* Respond to a pipe bind request.*******************************************************************/BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p){ RPC_HDR_BA hdr_ba; RPC_HDR_RB hdr_rb; RPC_HDR_AUTH auth_info; uint16 assoc_gid; fstring ack_pipe_name; prs_struct out_hdr_ba; prs_struct out_auth; prs_struct outgoing_rpc; int i = 0; int auth_len = 0; unsigned int auth_type = RPC_ANONYMOUS_AUTH_TYPE; /* No rebinds on a bound pipe - use alter context. */ if (p->pipe_bound) { DEBUG(2,("api_pipe_bind_req: rejecting bind request on bound pipe %s.\n", p->pipe_srv_name)); return setup_bind_nak(p); } prs_init( &outgoing_rpc, 0, p->mem_ctx, MARSHALL); /* * Marshall directly into the outgoing PDU space. We * must do this as we need to set to the bind response * header and are never sending more than one PDU here. */ prs_give_memory( &outgoing_rpc, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False); /* * Setup the memory to marshall the ba header, and the * auth footers. */ if(!prs_init(&out_hdr_ba, 1024, p->mem_ctx, MARSHALL)) { DEBUG(0,("api_pipe_bind_req: malloc out_hdr_ba failed.\n")); prs_mem_free(&outgoing_rpc); return False; } if(!prs_init(&out_auth, 1024, p->mem_ctx, MARSHALL)) { DEBUG(0,("api_pipe_bind_req: malloc out_auth failed.\n")); prs_mem_free(&outgoing_rpc); prs_mem_free(&out_hdr_ba); return False; } DEBUG(5,("api_pipe_bind_req: decode request. %d\n", __LINE__)); /* * Try and find the correct pipe name to ensure * that this is a pipe name we support. */ for (i = 0; i < rpc_lookup_size; i++) { if (strequal(rpc_lookup[i].pipe.clnt, p->name)) { DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n", rpc_lookup[i].pipe.clnt, rpc_lookup[i].pipe.srv)); fstrcpy(p->pipe_srv_name, rpc_lookup[i].pipe.srv); break; } } if (i == rpc_lookup_size) { if (NT_STATUS_IS_ERR(smb_probe_module("rpc", p->name))) { DEBUG(3,("api_pipe_bind_req: Unknown pipe name %s in bind request.\n", p->name )); prs_mem_free(&outgoing_rpc); prs_mem_free(&out_hdr_ba); prs_mem_free(&out_auth); return setup_bind_nak(p); } for (i = 0; i < rpc_lookup_size; i++) { if (strequal(rpc_lookup[i].pipe.clnt, p->name)) { DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n", rpc_lookup[i].pipe.clnt, rpc_lookup[i].pipe.srv)); fstrcpy(p->pipe_srv_name, rpc_lookup[i].pipe.srv); break; } } if (i == rpc_lookup_size) { DEBUG(0, ("module %s doesn't provide functions for pipe %s!\n", p->name, p->name)); goto err_exit; } } /* decode the bind request */ if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_in_p, 0)) { DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_RB struct.\n")); goto err_exit; } /* name has to be \PIPE\xxxxx */ fstrcpy(ack_pipe_name, "\\PIPE\\"); fstrcat(ack_pipe_name, p->pipe_srv_name); DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__)); /* * Check if this is an authenticated bind request. */ if (p->hdr.auth_len) { /* * Decode the authentication verifier. */ if(!smb_io_rpc_hdr_auth("", &auth_info, rpc_in_p, 0)) { DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_AUTH struct.\n")); goto err_exit; } auth_type = auth_info.auth_type; /* Work out if we have to sign or seal etc. */ switch (auth_info.auth_level) { case RPC_AUTH_LEVEL_INTEGRITY: p->auth.auth_level = PIPE_AUTH_LEVEL_INTEGRITY; break; case RPC_AUTH_LEVEL_PRIVACY: p->auth.auth_level = PIPE_AUTH_LEVEL_PRIVACY; break; default: DEBUG(0,("api_pipe_bind_req: unexpected auth level (%u).\n", (unsigned int)auth_info.auth_level )); goto err_exit; } } else { ZERO_STRUCT(auth_info); } assoc_gid = hdr_rb.bba.assoc_gid ? hdr_rb.bba.assoc_gid : 0x53f0; switch(auth_type) { case RPC_NTLMSSP_AUTH_TYPE: if (!pipe_ntlmssp_auth_bind(p, rpc_in_p, &auth_info, &out_auth)) { goto err_exit; } assoc_gid = 0x7a77; break; case RPC_SCHANNEL_AUTH_TYPE: if (!pipe_schannel_auth_bind(p, rpc_in_p, &auth_info, &out_auth)) { goto err_exit; } break; case RPC_SPNEGO_AUTH_TYPE: if (!pipe_spnego_auth_bind_negotiate(p, rpc_in_p, &auth_info, &out_auth)) { goto err_exit; } break; case RPC_ANONYMOUS_AUTH_TYPE: /* Unauthenticated bind request. */ /* We're finished - no more packets. */ p->auth.auth_type = PIPE_AUTH_TYPE_NONE; /* We must set the pipe auth_level here also. */ p->auth.auth_level = PIPE_AUTH_LEVEL_NONE; p->pipe_bound = True; break; default: DEBUG(0,("api_pipe_bind_req: unknown auth type %x requested.\n", auth_type )); goto err_exit; } /* * Create the bind response struct. */ /* If the requested abstract synt uuid doesn't match our client pipe, reject the bind_ack & set the transfer interface synt to all 0's, ver 0 (observed when NT5 attempts to bind to abstract interfaces unknown to NT4) Needed when adding entries to a DACL from NT5 - SK */ if(check_bind_req(p, &hdr_rb.rpc_context[0].abstract, &hdr_rb.rpc_context[0].transfer[0], hdr_rb.rpc_context[0].context_id )) { init_rpc_hdr_ba(&hdr_ba, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, assoc_gid, ack_pipe_name, 0x1, 0x0, 0x0, &hdr_rb.rpc_context[0].transfer[0]); } else { RPC_IFACE null_interface; ZERO_STRUCT(null_interface); /* Rejection reason: abstract syntax not supported */ init_rpc_hdr_ba(&hdr_ba, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, assoc_gid, ack_pipe_name, 0x1, 0x2, 0x1, &null_interface); p->pipe_bound = False; } /* * and marshall it. */ if(!smb_io_rpc_hdr_ba("", &hdr_ba, &out_hdr_ba, 0)) { DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR_BA failed.\n")); goto err_exit; } /* * Create the header, now we know the length. */ if (prs_offset(&out_auth)) { auth_len = prs_offset(&out_auth) - RPC_HDR_AUTH_LEN; } init_rpc_hdr(&p->hdr, RPC_BINDACK, RPC_FLG_FIRST | RPC_FLG_LAST, p->hdr.call_id, RPC_HEADER_LEN + prs_offset(&out_hdr_ba) + prs_offset(&out_auth), auth_len); /* * Marshall the header into the outgoing PDU. */ if(!smb_io_rpc_hdr("", &p->hdr, &outgoing_rpc, 0)) { DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR failed.\n")); goto err_exit; } /* * Now add the RPC_HDR_BA and any auth needed. */ if(!prs_append_prs_data( &outgoing_rpc, &out_hdr_ba)) { DEBUG(0,("api_pipe_bind_req: append of RPC_HDR_BA failed.\n")); goto err_exit; } if (auth_len && !prs_append_prs_data( &outgoing_rpc, &out_auth)) { DEBUG(0,("api_pipe_bind_req: append of auth info failed.\n")); goto err_exit; } /* * Setup the lengths for the initial reply. */ p->out_data.data_sent_length = 0; p->out_data.current_pdu_len = prs_offset(&outgoing_rpc); p->out_data.current_pdu_sent = 0; prs_mem_free(&out_hdr_ba); prs_mem_free(&out_auth); return True; err_exit: prs_mem_free(&outgoing_rpc); prs_mem_free(&out_hdr_ba); prs_mem_free(&out_auth); return setup_bind_nak(p);}/**************************************************************************** Deal with an alter context call. Can be third part of 3 leg auth request for SPNEGO calls.****************************************************************************/BOOL api_pipe_alter_context(pipes_struct *p, prs_struct *rpc_in_p){ RPC_HDR_BA hdr_ba; RPC_HDR_RB hdr_rb; RPC_HDR_AUTH auth_info; uint16 assoc_gid; fstring ack_pipe_name; prs_struct out_hdr_ba; prs_struct out_auth; prs_struct outgoing_rpc; int auth_len = 0; prs_init( &outgoing_rpc, 0, p->mem_ctx, MARSHALL); /* * Marshall directly into the outgoing PDU space. We * must do this as we need to set to the bind response * header and are never sending more than one PDU here. */ prs_give_memory( &outgoing_rpc, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False); /* * Setup the memory to marshall the ba header, and the * auth footers. */ if(!prs_init(&out_hdr_ba, 1024, p->mem_ctx, MARSHALL)) { DEBUG(0,("api_pipe_alter_context: malloc out_hdr_ba failed.\n")); prs_mem_free(&outgoing_rpc); return False; } if(!prs_init(&out_auth, 1024, p->mem_ctx, MARSHALL)) { DEBUG(0,("api_pipe_alter_context: malloc out_auth failed.\n")); prs_mem_free(&outgoing_rpc); prs_mem_free(&out_hdr_ba); return False; } DEBUG(5,("api_pipe_alter_context: decode request. %d\n", __LINE__)); /* decode the alter context request */ if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_in_p, 0)) { DEBUG(0,("api_pipe_alter_context: unable to unmarshall RPC_HDR_RB struct.\n")); goto err_exit; } /* secondary address CAN be NULL * as the specs say it's ignored. * It MUST be NULL to have the spoolss working. */ fstrcpy(ack_pipe_name,""); DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__)); /* * Check if this is an authenticated alter context request. */ if (p->hdr.auth_len != 0) { /* * Decode the authentication verifier. */ if(!smb_io_rpc_hdr_auth("", &auth_info, rpc_in_p, 0)) { DEBUG(0,("api_pipe_alter_context: unable to unmarshall RPC_HDR_AUTH struct.\n")); goto err_exit; } /* * Currently only the SPNEGO auth type uses the alter ctx * response in place of the NTLMSSP auth3 type. */ if (auth_info.auth_type == RPC_SPNEGO_AUTH_TYPE) { /* We can only finish if the pipe is unbound. */ if (!p->pipe_bound) { if (!pipe_spnego_auth_bind_continue(p, rpc_in_p, &auth_info, &out_auth)) { goto err_exit; } } else { goto err_exit; } } } else { ZERO_STRUCT(auth_info); } assoc_gid = hdr_rb.bba.assoc_gid ? hdr_rb.bba.assoc_gid : 0x53f0; /* * Create the bind response struct. */ /* If the requested abstract synt uuid doesn't match our client pipe, reject the bind_ack & set the transfer interface synt to all 0's, ver 0 (observed when NT5 attempts to bind to abstract interfaces unknown to NT4) Needed when adding entries to a DACL from NT5 - SK */ if(check_bind_req(p, &hdr_rb.rpc_context[0].abstract, &hdr_rb.rpc_context[0].transfer[0], hdr_rb.rpc_context[0].context_id )) { init_rpc_hdr_ba(&hdr_ba, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, assoc_gid, ack_pipe_name, 0x1, 0x0, 0x0, &hdr_rb.rpc_context[0].transfer[0]); } else { RPC_IFACE null_interface; ZERO_STRUCT(null_interface); /* Rejection reason: abstract syntax not supported */ init_rpc_hdr_ba(&hdr_ba, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, assoc_gid, ack_pipe_name, 0x1, 0x2, 0x1, &null_interface); p->pipe_bound = False; } /* * and marshall it. */ if(!smb_io_rpc_hdr_ba("", &hdr_ba, &out_hdr_ba, 0)) { DEBUG(0,("api_pipe_alter_context: marshalling of RPC_HDR_BA failed.\n")); goto err_exit; } /* * Create the header, now we know the length. */ if (prs_offset(&out_auth)) { auth_len = prs_offset(&out_auth) - RPC_HDR_AUTH_LEN; } init_rpc_hdr(&p->hdr, RPC_ALTCONTRESP, RPC_FLG_FIRST | RPC_FLG_LAST, p->hdr.call_id, RPC_HEADER_LEN + prs_offset(&out_hdr_ba) + prs_offset(&out_auth), auth_len); /* * Marshall the header into the outgoing PDU. */ if(!smb_io_rpc_hdr("", &p->hdr, &outgoing_rpc, 0)) { DEBUG(0,("api_pipe_alter_context: marshalling of RPC_HDR failed.\n"));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -