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

📄 srv_pipe.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
		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_alter_context: 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_alter_context: 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 NTLMSSP sign & seal processing on an RPC request.****************************************************************************/BOOL api_pipe_ntlmssp_auth_process(pipes_struct *p, prs_struct *rpc_in,					uint32 *p_ss_padding_len, NTSTATUS *pstatus){	RPC_HDR_AUTH auth_info;	uint32 auth_len = p->hdr.auth_len;	uint32 save_offset = prs_offset(rpc_in);	AUTH_NTLMSSP_STATE *a = p->auth.a_u.auth_ntlmssp_state;	unsigned char *data = NULL;	size_t data_len;	unsigned char *full_packet_data = NULL;	size_t full_packet_data_len;	DATA_BLOB auth_blob;		*pstatus = NT_STATUS_OK;	if (p->auth.auth_level == PIPE_AUTH_LEVEL_NONE || p->auth.auth_level == PIPE_AUTH_LEVEL_CONNECT) {		return True;	}	if (!a) {		*pstatus = NT_STATUS_INVALID_PARAMETER;		return False;	}	/* Ensure there's enough data for an authenticated request. */	if ((auth_len > RPC_MAX_SIGN_SIZE) ||			(RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_HDR_AUTH_LEN + auth_len > p->hdr.frag_len)) {		DEBUG(0,("api_pipe_ntlmssp_auth_process: auth_len %u is too large.\n",			(unsigned int)auth_len ));		*pstatus = NT_STATUS_INVALID_PARAMETER;		return False;	}	/*	 * We need the full packet data + length (minus auth stuff) as well as the packet data + length	 * after the RPC header.  	 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal	 * functions as NTLMv2 checks the rpc headers also.	 */	data = (unsigned char *)(prs_data_p(rpc_in) + RPC_HDR_REQ_LEN);	data_len = (size_t)(p->hdr.frag_len - RPC_HEADER_LEN - RPC_HDR_REQ_LEN - RPC_HDR_AUTH_LEN - auth_len);	full_packet_data = p->in_data.current_in_pdu;	full_packet_data_len = p->hdr.frag_len - auth_len;	/* Pull the auth header and the following data into a blob. */	if(!prs_set_offset(rpc_in, RPC_HDR_REQ_LEN + data_len)) {		DEBUG(0,("api_pipe_ntlmssp_auth_process: cannot move offset to %u.\n",			(unsigned int)RPC_HDR_REQ_LEN + (unsigned int)data_len ));		*pstatus = NT_STATUS_INVALID_PARAMETER;		return False;	}	if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, rpc_in, 0)) {		DEBUG(0,("api_pipe_ntlmssp_auth_process: failed to unmarshall RPC_HDR_AUTH.\n"));		*pstatus = NT_STATUS_INVALID_PARAMETER;		return False;	}	auth_blob.data = (unsigned char *)prs_data_p(rpc_in) + prs_offset(rpc_in);	auth_blob.length = auth_len;		switch (p->auth.auth_level) {		case PIPE_AUTH_LEVEL_PRIVACY:			/* Data is encrypted. */			*pstatus = ntlmssp_unseal_packet(a->ntlmssp_state,							data, data_len,							full_packet_data,							full_packet_data_len,							&auth_blob);			if (!NT_STATUS_IS_OK(*pstatus)) {				return False;			}			break;		case PIPE_AUTH_LEVEL_INTEGRITY:			/* Data is signed. */			*pstatus = ntlmssp_check_packet(a->ntlmssp_state,							data, data_len,							full_packet_data,							full_packet_data_len,							&auth_blob);			if (!NT_STATUS_IS_OK(*pstatus)) {				return False;			}			break;		default:			*pstatus = NT_STATUS_INVALID_PARAMETER;			return False;	}	/*	 * Return the current pointer to the data offset.	 */	if(!prs_set_offset(rpc_in, save_offset)) {		DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",			(unsigned int)save_offset ));		*pstatus = NT_STATUS_INVALID_PARAMETER;		return False;	}	/*	 * Remember the padding length. We must remove it from the real data	 * stream once the sign/seal is done.	 */	*p_ss_padding_len = auth_info.auth_pad_len;	return True;}/**************************************************************************** Deal with schannel processing on an RPC request.****************************************************************************/BOOL api_pipe_schannel_process(pipes_struct *p, prs_struct *rpc_in, uint32 *p_ss_padding_len){	uint32 data_len;	uint32 auth_len;	uint32 save_offset = prs_offset(rpc_in);	RPC_HDR_AUTH auth_info;	RPC_AUTH_SCHANNEL_CHK schannel_chk;	auth_len = p->hdr.auth_len;	if (auth_len != RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {		DEBUG(0,("Incorrect auth_len %u.\n", (unsigned int)auth_len ));		return False;	}	/*	 * The following is that length of the data we must verify or unseal.	 * This doesn't include the RPC headers or the auth_len or the RPC_HDR_AUTH_LEN	 * preceeding the auth_data.	 */	if (p->hdr.frag_len < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_HDR_AUTH_LEN + auth_len) {		DEBUG(0,("Incorrect frag %u, auth %u.\n",			(unsigned int)p->hdr.frag_len,			(unsigned int)auth_len ));		return False;	}	data_len = p->hdr.frag_len - RPC_HEADER_LEN - RPC_HDR_REQ_LEN - 		RPC_HDR_AUTH_LEN - auth_len;		DEBUG(5,("data %d auth %d\n", data_len, auth_len));	if(!prs_set_offset(rpc_in, RPC_HDR_REQ_LEN + data_len)) {		DEBUG(0,("cannot move offset to %u.\n",			 (unsigned int)RPC_HDR_REQ_LEN + data_len ));		return False;	}	if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, rpc_in, 0)) {		DEBUG(0,("failed to unmarshall RPC_HDR_AUTH.\n"));		return False;	}	if (auth_info.auth_type != RPC_SCHANNEL_AUTH_TYPE) {		DEBUG(0,("Invalid auth info %d on schannel\n",			 auth_info.auth_type));		return False;	}	if(!smb_io_rpc_auth_schannel_chk("", RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN, &schannel_chk, rpc_in, 0)) {		DEBUG(0,("failed to unmarshal RPC_AUTH_SCHANNEL_CHK.\n"));		return False;	}	if (!schannel_decode(p->auth.a_u.schannel_auth,			   p->auth.auth_level,			   SENDER_IS_INITIATOR,			   &schannel_chk,			   prs_data_p(rpc_in)+RPC_HDR_REQ_LEN, data_len)) {		DEBUG(3,("failed to decode PDU\n"));		return False;	}	/*	 * Return the current pointer to the data offset.	 */	if(!prs_set_offset(rpc_in, save_offset)) {		DEBUG(0,("failed to set offset back to %u\n",			 (unsigned int)save_offset ));		return False;	}	/* The sequence number gets incremented on both send and receive. */	p->auth.a_u.schannel_auth->seq_num++;	/*	 * Remember the padding length. We must remove it from the real data	 * stream once the sign/seal is done.	 */	*p_ss_padding_len = auth_info.auth_pad_len;	return True;}/**************************************************************************** Return a user struct for a pipe user.****************************************************************************/struct current_user *get_current_user(struct current_user *user, pipes_struct *p){	if (p->pipe_bound &&			(p->auth.auth_type == PIPE_AUTH_TYPE_NTLMSSP ||			(p->auth.auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP))) {		memcpy(user, &p->pipe_user, sizeof(struct current_user));	} else {		memcpy(user, &current_user, sizeof(struct current_user));	}	return user;}/**************************************************************************** Find the set of RPC functions associated with this context_id****************************************************************************/static PIPE_RPC_FNS* find_pipe_fns_by_context( PIPE_RPC_FNS *list, uint32 context_id ){	PIPE_RPC_FNS *fns = NULL;	PIPE_RPC_FNS *tmp = NULL;		if ( !list ) {		DEBUG(0,("find_pipe_fns_by_context: ERROR!  No context list for pipe!\n"));		return NULL;	}		for (tmp=list; tmp; tmp=tmp->next ) {		if ( tmp->context_id == context_id )			break;	}		fns = tmp;		return fns;}/**************************************************************************** Memory cleanup.****************************************************************************/void free_pipe_rpc_context( PIPE_RPC_FNS *list ){	PIPE_RPC_FNS *tmp = list;	PIPE_RPC_FNS *tmp2;			while (tmp) {		tmp2 = tmp->next;		SAFE_FREE(tmp);		tmp = tmp2;	}	return;	}/**************************************************************************** Find the correct RPC function to call for this request. If the pipe is authenticated then become the correct UNIX user before doing the call.****************************************************************************/BOOL api_pipe_request(pipes_struct *p){	BOOL ret = False;	BOOL changed_user = False;	PIPE_RPC_FNS *pipe_fns;		if (p->pipe_bound &&			((p->auth.auth_type == PIPE_AUTH_TYPE_NTLMSSP) ||			 (p->auth.auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP))) {		if(!become_authenticated_pipe_user(p)) {			prs_mem_free(&p->out_data.rdata);			return False;		}		changed_user = True;	}	DEBUG(5, ("Requested \\PIPE\\%s\n", p->name));		/* get the set of RPC functions for this context */		pipe_fns = find_pipe_fns_by_context(p->contexts, p->hdr_req.context_id);		if ( pipe_fns ) {		set_current_rpc_talloc(p->mem_ctx);		ret = api_rpcTNP(p, p->name, pipe_fns->cmds, pipe_fns->n_cmds);		set_current_rpc_talloc(NULL);		}	else {		DEBUG(0,("api_pipe_request: No rpc function table associated with context [%d] on pipe [%s]\n",			p->hdr_req.context_id, p->name));	}	if (changed_user) {		unbecome_authenticated_pipe_user();	}	return ret;}/******************************************************************* Calls the underlying RPC function for a named pipe. ********************************************************************/BOOL api_rpcTNP(pipes_struct *p, const char *rpc_name, 		const struct api_struct *api_rpc_cmds, int n_cmds){	int fn_num;	fstring name;	uint32 offset1, offset2; 	/* interpret the command */	DEBUG(4,("api_rpcTNP: %s op 0x%x - ", rpc_name, p->hdr_req.opnum));	slprintf(name, sizeof(name)-1, "in_%s", rpc_name);	prs_dump(name, p->hdr_req.opnum, &p->in_data.data);	for (fn_num = 0; fn_num < n_cmds; fn_num++) {		if (api_rpc_cmds[fn_num].opnum == p->hdr_req.opnum && api_rpc_cmds[fn_num].fn != NULL) {			DEBUG(3,("api_rpcTNP: rpc command: %s\n", api_rpc_cmds[fn_num].name));			break;		}	}	if (fn_num == n_cmds) {		/*		 * For an unknown RPC just return a fault PDU but		 * return True to allow RPC's on the pipe to continue		 * and not put the pipe into fault state. JRA.		 */		DEBUG(4, ("unknown\n"));		setup_fault_pdu(p, NT_STATUS(0x1c010002));		return True;	}	offset1 = prs_offset(&p->out_data.rdata);        DEBUG(6, ("api_rpc_cmds[%d].fn == %p\n",                 fn_num, api_rpc_cmds[fn_num].fn));	/* do the actual command */	if(!api_rpc_cmds[fn_num].fn(p)) {		DEBUG(0,("api_rpcTNP: %s: %s failed.\n", rpc_name, api_rpc_cmds[fn_num].name));		prs_mem_free(&p->out_data.rdata);		return False;	}	if (p->bad_handle_fault_state) {		DEBUG(4,("api_rpcTNP: bad handle fault return.\n"));		p->bad_handle_fault_state = False;		setup_fault_pdu(p, NT_STATUS(0x1C00001A));		return True;	}	slprintf(name, sizeof(name)-1, "out_%s", rpc_name);	offset2 = prs_offset(&p->out_data.rdata);	prs_set_offset(&p->out_data.rdata, offset1);	prs_dump(name, p->hdr_req.opnum, &p->out_data.rdata);	prs_set_offset(&p->out_data.rdata, offset2);	DEBUG(5,("api_rpcTNP: called %s successfully\n", rpc_name));	/* Check for buffer underflow in rpc parsing */	if ((DEBUGLEVEL >= 10) && 	    (prs_offset(&p->in_data.data) != prs_data_size(&p->in_data.data))) {		size_t data_len = prs_data_size(&p->in_data.data) - prs_offset(&p->in_data.data);		char *data = SMB_MALLOC(data_len);		DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n"));		if (data) {			prs_uint8s(False, "", &p->in_data.data, 0, (unsigned char *)data, (uint32)data_len);			SAFE_FREE(data);		}	}	return True;}/**************************************************************************************************************************************/void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns ){	struct api_struct *cmds = NULL;	int               n_cmds = 0;	switch ( idx ) {		case PI_LSARPC:			lsa_get_pipe_fns( &cmds, &n_cmds );			break;		case PI_LSARPC_DS:			lsa_ds_get_pipe_fns( &cmds, &n_cmds );			break;		case PI_SAMR:			samr_get_pipe_fns( &cmds, &n_cmds );			break;		case PI_NETLOGON:			netlog_get_pipe_fns( &cmds, &n_cmds );			break;		case PI_SRVSVC:			srvsvc_get_pipe_fns( &cmds, &n_cmds );			break;		case PI_WKSSVC:			wkssvc_get_pipe_fns( &cmds, &n_cmds );			break;		case PI_WINREG:			reg_get_pipe_fns( &cmds, &n_cmds );			break;		case PI_SPOOLSS:			spoolss_get_pipe_fns( &cmds, &n_cmds );			break;		case PI_NETDFS:			netdfs_get_pipe_fns( &cmds, &n_cmds );			

⌨️ 快捷键说明

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