⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 srv_pipe.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*  *  Unix SMB/CIFS implementation. *  RPC Pipe client / server routines *  Almost completely rewritten by (C) Jeremy Allison 2005. *   *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. *   *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. *   *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//*  this module apparently provides an implementation of DCE/RPC over a *  named pipe (IPC$ connection using SMBtrans).  details of DCE/RPC *  documentation are available (in on-line form) from the X-Open group. * *  this module should provide a level of abstraction between SMB *  and DCE/RPC, while minimising the amount of mallocs, unnecessary *  data copies, and network traffic. * */#include "includes.h"extern struct pipe_id_info pipe_names[];extern struct current_user current_user;#undef DBGC_CLASS#define DBGC_CLASS DBGC_RPC_SRVstatic void free_pipe_ntlmssp_auth_data(struct pipe_auth_data *auth){	AUTH_NTLMSSP_STATE *a = auth->a_u.auth_ntlmssp_state;	if (a) {		auth_ntlmssp_end(&a);	}	auth->a_u.auth_ntlmssp_state = NULL;}/******************************************************************* Generate the next PDU to be returned from the data in p->rdata.  Handle NTLMSSP. ********************************************************************/static BOOL create_next_pdu_ntlmssp(pipes_struct *p){	RPC_HDR_RESP hdr_resp;	uint32 ss_padding_len = 0;	uint32 data_space_available;	uint32 data_len_left;	uint32 data_len;	prs_struct outgoing_pdu;	NTSTATUS status;	DATA_BLOB auth_blob;	RPC_HDR_AUTH auth_info;	uint8 auth_type, auth_level;	AUTH_NTLMSSP_STATE *a = p->auth.a_u.auth_ntlmssp_state;	/*	 * If we're in the fault state, keep returning fault PDU's until	 * the pipe gets closed. JRA.	 */	if(p->fault_state) {		setup_fault_pdu(p, NT_STATUS(0x1c010002));		return True;	}	memset((char *)&hdr_resp, '\0', sizeof(hdr_resp));	/* Change the incoming request header to a response. */	p->hdr.pkt_type = RPC_RESPONSE;	/* Set up rpc header flags. */	if (p->out_data.data_sent_length == 0) {		p->hdr.flags = RPC_FLG_FIRST;	} else {		p->hdr.flags = 0;	}	/*	 * Work out how much we can fit in a single PDU.	 */	data_len_left = prs_offset(&p->out_data.rdata) - p->out_data.data_sent_length;	/*	 * Ensure there really is data left to send.	 */	if(!data_len_left) {		DEBUG(0,("create_next_pdu_ntlmssp: no data left to send !\n"));		return False;	}	data_space_available = sizeof(p->out_data.current_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN -					RPC_HDR_AUTH_LEN - NTLMSSP_SIG_SIZE;	/*	 * The amount we send is the minimum of the available	 * space and the amount left to send.	 */	data_len = MIN(data_len_left, data_space_available);	/*	 * Set up the alloc hint. This should be the data left to	 * send.	 */	hdr_resp.alloc_hint = data_len_left;	/*	 * Work out if this PDU will be the last.	 */	if(p->out_data.data_sent_length + data_len >= prs_offset(&p->out_data.rdata)) {		p->hdr.flags |= RPC_FLG_LAST;		if (data_len_left % 8) {			ss_padding_len = 8 - (data_len_left % 8);			DEBUG(10,("create_next_pdu_ntlmssp: adding sign/seal padding of %u\n",				ss_padding_len ));		}	}	/*	 * Set up the header lengths.	 */	p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN +			data_len + ss_padding_len +			RPC_HDR_AUTH_LEN + NTLMSSP_SIG_SIZE;	p->hdr.auth_len = NTLMSSP_SIG_SIZE;	/*	 * Init the parse struct to point at the outgoing	 * data.	 */	prs_init( &outgoing_pdu, 0, p->mem_ctx, MARSHALL);	prs_give_memory( &outgoing_pdu, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False);	/* Store the header in the data stream. */	if(!smb_io_rpc_hdr("hdr", &p->hdr, &outgoing_pdu, 0)) {		DEBUG(0,("create_next_pdu_ntlmssp: failed to marshall RPC_HDR.\n"));		prs_mem_free(&outgoing_pdu);		return False;	}	if(!smb_io_rpc_hdr_resp("resp", &hdr_resp, &outgoing_pdu, 0)) {		DEBUG(0,("create_next_pdu_ntlmssp: failed to marshall RPC_HDR_RESP.\n"));		prs_mem_free(&outgoing_pdu);		return False;	}	/* Copy the data into the PDU. */	if(!prs_append_some_prs_data(&outgoing_pdu, &p->out_data.rdata, p->out_data.data_sent_length, data_len)) {		DEBUG(0,("create_next_pdu_ntlmssp: failed to copy %u bytes of data.\n", (unsigned int)data_len));		prs_mem_free(&outgoing_pdu);		return False;	}	/* Copy the sign/seal padding data. */	if (ss_padding_len) {		char pad[8];		memset(pad, '\0', 8);		if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding_len)) {			DEBUG(0,("create_next_pdu_ntlmssp: failed to add %u bytes of pad data.\n",					(unsigned int)ss_padding_len));			prs_mem_free(&outgoing_pdu);			return False;		}	}	/* Now write out the auth header and null blob. */	if (p->auth.auth_type == PIPE_AUTH_TYPE_NTLMSSP) {		auth_type = RPC_NTLMSSP_AUTH_TYPE;	} else {		auth_type = RPC_SPNEGO_AUTH_TYPE;	}	if (p->auth.auth_level == PIPE_AUTH_LEVEL_PRIVACY) {		auth_level = RPC_AUTH_LEVEL_PRIVACY;	} else {		auth_level = RPC_AUTH_LEVEL_INTEGRITY;	}	init_rpc_hdr_auth(&auth_info, auth_type, auth_level, ss_padding_len, 1 /* context id. */);	if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) {		DEBUG(0,("create_next_pdu_ntlmssp: failed to marshall RPC_HDR_AUTH.\n"));		prs_mem_free(&outgoing_pdu);		return False;	}	/* Generate the sign blob. */	switch (p->auth.auth_level) {		case PIPE_AUTH_LEVEL_PRIVACY:			/* Data portion is encrypted. */			status = ntlmssp_seal_packet(a->ntlmssp_state,							(unsigned char *)prs_data_p(&outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,							data_len + ss_padding_len,							(unsigned char *)prs_data_p(&outgoing_pdu),							(size_t)prs_offset(&outgoing_pdu),							&auth_blob);			if (!NT_STATUS_IS_OK(status)) {				data_blob_free(&auth_blob);				prs_mem_free(&outgoing_pdu);				return False;			}			break;		case PIPE_AUTH_LEVEL_INTEGRITY:			/* Data is signed. */			status = ntlmssp_sign_packet(a->ntlmssp_state,							(unsigned char *)prs_data_p(&outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,							data_len + ss_padding_len,							(unsigned char *)prs_data_p(&outgoing_pdu),							(size_t)prs_offset(&outgoing_pdu),							&auth_blob);			if (!NT_STATUS_IS_OK(status)) {				data_blob_free(&auth_blob);				prs_mem_free(&outgoing_pdu);				return False;			}			break;		default:			prs_mem_free(&outgoing_pdu);			return False;	}	/* Append the auth blob. */	if (!prs_copy_data_in(&outgoing_pdu, (char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {		DEBUG(0,("create_next_pdu_ntlmssp: failed to add %u bytes auth blob.\n",				(unsigned int)NTLMSSP_SIG_SIZE));		data_blob_free(&auth_blob);		prs_mem_free(&outgoing_pdu);		return False;	}	data_blob_free(&auth_blob);	/*	 * Setup the counts for this PDU.	 */	p->out_data.data_sent_length += data_len;	p->out_data.current_pdu_len = p->hdr.frag_len;	p->out_data.current_pdu_sent = 0;	prs_mem_free(&outgoing_pdu);	return True;}/******************************************************************* Generate the next PDU to be returned from the data in p->rdata.  Return an schannel authenticated fragment. ********************************************************************/static BOOL create_next_pdu_schannel(pipes_struct *p){	RPC_HDR_RESP hdr_resp;	uint32 ss_padding_len = 0;	uint32 data_len;	uint32 data_space_available;	uint32 data_len_left;	prs_struct outgoing_pdu;	uint32 data_pos;	/*	 * If we're in the fault state, keep returning fault PDU's until	 * the pipe gets closed. JRA.	 */	if(p->fault_state) {		setup_fault_pdu(p, NT_STATUS(0x1c010002));		return True;	}	memset((char *)&hdr_resp, '\0', sizeof(hdr_resp));	/* Change the incoming request header to a response. */	p->hdr.pkt_type = RPC_RESPONSE;	/* Set up rpc header flags. */	if (p->out_data.data_sent_length == 0) {		p->hdr.flags = RPC_FLG_FIRST;	} else {		p->hdr.flags = 0;	}	/*	 * Work out how much we can fit in a single PDU.	 */	data_len_left = prs_offset(&p->out_data.rdata) - p->out_data.data_sent_length;	/*	 * Ensure there really is data left to send.	 */	if(!data_len_left) {		DEBUG(0,("create_next_pdu_schannel: no data left to send !\n"));		return False;	}	data_space_available = sizeof(p->out_data.current_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN -					RPC_HDR_AUTH_LEN - RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;	/*	 * The amount we send is the minimum of the available	 * space and the amount left to send.	 */	data_len = MIN(data_len_left, data_space_available);	/*	 * Set up the alloc hint. This should be the data left to	 * send.	 */	hdr_resp.alloc_hint = data_len_left;	/*	 * Work out if this PDU will be the last.	 */	if(p->out_data.data_sent_length + data_len >= prs_offset(&p->out_data.rdata)) {		p->hdr.flags |= RPC_FLG_LAST;		if (data_len_left % 8) {			ss_padding_len = 8 - (data_len_left % 8);			DEBUG(10,("create_next_pdu_schannel: adding sign/seal padding of %u\n",				ss_padding_len ));		}	}	p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len + ss_padding_len +				RPC_HDR_AUTH_LEN + RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;	p->hdr.auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;	/*	 * Init the parse struct to point at the outgoing	 * data.	 */	prs_init( &outgoing_pdu, 0, p->mem_ctx, MARSHALL);	prs_give_memory( &outgoing_pdu, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False);	/* Store the header in the data stream. */	if(!smb_io_rpc_hdr("hdr", &p->hdr, &outgoing_pdu, 0)) {		DEBUG(0,("create_next_pdu_schannel: failed to marshall RPC_HDR.\n"));		prs_mem_free(&outgoing_pdu);		return False;	}	if(!smb_io_rpc_hdr_resp("resp", &hdr_resp, &outgoing_pdu, 0)) {		DEBUG(0,("create_next_pdu_schannel: failed to marshall RPC_HDR_RESP.\n"));		prs_mem_free(&outgoing_pdu);		return False;	}	/* Store the current offset. */	data_pos = prs_offset(&outgoing_pdu);	/* Copy the data into the PDU. */	if(!prs_append_some_prs_data(&outgoing_pdu, &p->out_data.rdata, p->out_data.data_sent_length, data_len)) {		DEBUG(0,("create_next_pdu_schannel: failed to copy %u bytes of data.\n", (unsigned int)data_len));		prs_mem_free(&outgoing_pdu);		return False;	}	/* Copy the sign/seal padding data. */	if (ss_padding_len) {		char pad[8];		memset(pad, '\0', 8);		if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding_len)) {			DEBUG(0,("create_next_pdu_schannel: failed to add %u bytes of pad data.\n", (unsigned int)ss_padding_len));			prs_mem_free(&outgoing_pdu);			return False;		}	}	{		/*		 * Schannel processing.		 */		char *data;		RPC_HDR_AUTH auth_info;		RPC_AUTH_SCHANNEL_CHK verf;		data = prs_data_p(&outgoing_pdu) + data_pos;		/* Check it's the type of reply we were expecting to decode */		init_rpc_hdr_auth(&auth_info,				RPC_SCHANNEL_AUTH_TYPE,				p->auth.auth_level == PIPE_AUTH_LEVEL_PRIVACY ?					RPC_AUTH_LEVEL_PRIVACY : RPC_AUTH_LEVEL_INTEGRITY,				ss_padding_len, 1);		if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) {			DEBUG(0,("create_next_pdu_schannel: failed to marshall RPC_HDR_AUTH.\n"));			prs_mem_free(&outgoing_pdu);			return False;		}		schannel_encode(p->auth.a_u.schannel_auth, 			      p->auth.auth_level,			      SENDER_IS_ACCEPTOR,			      &verf, data, data_len + ss_padding_len);		if (!smb_io_rpc_auth_schannel_chk("", RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN, 				&verf, &outgoing_pdu, 0)) {			prs_mem_free(&outgoing_pdu);			return False;		}		p->auth.a_u.schannel_auth->seq_num++;	}	/*	 * Setup the counts for this PDU.	 */	p->out_data.data_sent_length += data_len;	p->out_data.current_pdu_len = p->hdr.frag_len;	p->out_data.current_pdu_sent = 0;	prs_mem_free(&outgoing_pdu);	return True;}/******************************************************************* Generate the next PDU to be returned from the data in p->rdata.  No authentication done.********************************************************************/static BOOL create_next_pdu_noauth(pipes_struct *p){	RPC_HDR_RESP hdr_resp;	uint32 data_len;	uint32 data_space_available;	uint32 data_len_left;	prs_struct outgoing_pdu;	/*	 * If we're in the fault state, keep returning fault PDU's until	 * the pipe gets closed. JRA.	 */	if(p->fault_state) {		setup_fault_pdu(p, NT_STATUS(0x1c010002));		return True;	}	memset((char *)&hdr_resp, '\0', sizeof(hdr_resp));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -