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

📄 srv_pipe_hnd.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
		 * This is an error - data is being received and there is no		 * space in the PDU. Free the received data and go into the fault state.		 */		DEBUG(0,("process_incoming_data: No space in incoming pdu buffer. Current size = %u \incoming data size = %u\n", (unsigned int)p->in_data.pdu_received_len, (unsigned int)n ));		set_incoming_fault(p);		return -1;	}	/*	 * If we have no data already, wait until we get at least a RPC_HEADER_LEN	 * number of bytes before we can do anything.	 */	if((p->in_data.pdu_needed_len == 0) && (p->in_data.pdu_received_len < RPC_HEADER_LEN)) {		/*		 * Always return here. If we have more data then the RPC_HEADER		 * will be processed the next time around the loop.		 */		return fill_rpc_header(p, data, data_to_copy);	}	/*	 * At this point we know we have at least an RPC_HEADER_LEN amount of data	 * stored in current_in_pdu.	 */	/*	 * If pdu_needed_len is zero this is a new pdu. 	 * Unmarshall the header so we know how much more	 * data we need, then loop again.	 */	if(p->in_data.pdu_needed_len == 0) {		ssize_t rret = unmarshall_rpc_header(p);		if (rret == -1 || p->in_data.pdu_needed_len > 0) {			return rret;		}		/* If rret == 0 and pdu_needed_len == 0 here we have a PDU that consists		   of an RPC_HEADER only. This is a RPC_SHUTDOWN, RPC_CO_CANCEL or RPC_ORPHANED		   pdu type. Deal with this in process_complete_pdu(). */	}	/*	 * Ok - at this point we have a valid RPC_HEADER in p->hdr.	 * Keep reading until we have a full pdu.	 */	data_to_copy = MIN(data_to_copy, p->in_data.pdu_needed_len);	/*	 * Copy as much of the data as we need into the current_in_pdu buffer.	 * pdu_needed_len becomes zero when we have a complete pdu.	 */	memcpy( (char *)&p->in_data.current_in_pdu[p->in_data.pdu_received_len], data, data_to_copy);	p->in_data.pdu_received_len += data_to_copy;	p->in_data.pdu_needed_len -= data_to_copy;	/*	 * Do we have a complete PDU ?	 * (return the number of bytes handled in the call)	 */	if(p->in_data.pdu_needed_len == 0) {		process_complete_pdu(p);		return data_to_copy;	}	DEBUG(10,("process_incoming_data: not a complete PDU yet. pdu_received_len = %u, pdu_needed_len = %u\n",		(unsigned int)p->in_data.pdu_received_len, (unsigned int)p->in_data.pdu_needed_len ));	return (ssize_t)data_to_copy;}/**************************************************************************** Accepts incoming data on an rpc pipe.****************************************************************************/ssize_t write_to_pipe(smb_np_struct *p, char *data, size_t n){	DEBUG(6,("write_to_pipe: %x", p->pnum));	DEBUG(6,(" name: %s open: %s len: %d\n",		 p->name, BOOLSTR(p->open), (int)n));	dump_data(50, data, n);	return p->namedpipe_write(p->np_state, data, n);}/**************************************************************************** Accepts incoming data on an internal rpc pipe.****************************************************************************/static ssize_t write_to_internal_pipe(void *np_conn, char *data, size_t n){	pipes_struct *p = (pipes_struct*)np_conn;	size_t data_left = n;	while(data_left) {		ssize_t data_used;		DEBUG(10,("write_to_pipe: data_left = %u\n", (unsigned int)data_left ));		data_used = process_incoming_data(p, data, data_left);		DEBUG(10,("write_to_pipe: data_used = %d\n", (int)data_used ));		if(data_used < 0) {			return -1;		}		data_left -= data_used;		data += data_used;	}		return n;}/**************************************************************************** Replies to a request to read data from a pipe. Headers are interspersed with the data at PDU intervals. By the time this function is called, the start of the data could possibly have been read by an SMBtrans (file_offset != 0). Calling create_rpc_reply() here is a hack. The data should already have been prepared into arrays of headers + data stream sections.****************************************************************************/ssize_t read_from_pipe(smb_np_struct *p, char *data, size_t n,		BOOL *is_data_outstanding){	if (!p || !p->open) {		DEBUG(0,("read_from_pipe: pipe not open\n"));		return -1;			}	DEBUG(6,("read_from_pipe: %x", p->pnum));	return p->namedpipe_read(p->np_state, data, n, is_data_outstanding);}/**************************************************************************** Replies to a request to read data from a pipe. Headers are interspersed with the data at PDU intervals. By the time this function is called, the start of the data could possibly have been read by an SMBtrans (file_offset != 0). Calling create_rpc_reply() here is a hack. The data should already have been prepared into arrays of headers + data stream sections.****************************************************************************/static ssize_t read_from_internal_pipe(void *np_conn, char *data, size_t n,		BOOL *is_data_outstanding){	pipes_struct *p = (pipes_struct*)np_conn;	uint32 pdu_remaining = 0;	ssize_t data_returned = 0;	if (!p) {		DEBUG(0,("read_from_pipe: pipe not open\n"));		return -1;			}	DEBUG(6,(" name: %s len: %u\n", p->name, (unsigned int)n));	/*	 * We cannot return more than one PDU length per	 * read request.	 */	/*	 * This condition should result in the connection being closed.  	 * Netapp filers seem to set it to 0xffff which results in domain	 * authentications failing.  Just ignore it so things work.	 */	if(n > RPC_MAX_PDU_FRAG_LEN) {                DEBUG(5,("read_from_pipe: too large read (%u) requested on \pipe %s. We can only service %d sized reads.\n", (unsigned int)n, p->name, RPC_MAX_PDU_FRAG_LEN ));	}	/* 	 * Determine if there is still data to send in the	 * pipe PDU buffer. Always send this first. Never	 * send more than is left in the current PDU. The	 * client should send a new read request for a new	 * PDU.	 */	if((pdu_remaining = p->out_data.current_pdu_len - p->out_data.current_pdu_sent) > 0) {		data_returned = (ssize_t)MIN(n, pdu_remaining);		DEBUG(10,("read_from_pipe: %s: current_pdu_len = %u, current_pdu_sent = %u \returning %d bytes.\n", p->name, (unsigned int)p->out_data.current_pdu_len, 			(unsigned int)p->out_data.current_pdu_sent, (int)data_returned));		memcpy( data, &p->out_data.current_pdu[p->out_data.current_pdu_sent], (size_t)data_returned);		p->out_data.current_pdu_sent += (uint32)data_returned;		goto out;	}	/*	 * At this point p->current_pdu_len == p->current_pdu_sent (which	 * may of course be zero if this is the first return fragment.	 */	DEBUG(10,("read_from_pipe: %s: fault_state = %d : data_sent_length \= %u, prs_offset(&p->out_data.rdata) = %u.\n",		p->name, (int)p->fault_state, (unsigned int)p->out_data.data_sent_length, (unsigned int)prs_offset(&p->out_data.rdata) ));	if(p->out_data.data_sent_length >= prs_offset(&p->out_data.rdata)) {		/*		 * We have sent all possible data, return 0.		 */		data_returned = 0;		goto out;	}	/*	 * We need to create a new PDU from the data left in p->rdata.	 * Create the header/data/footers. This also sets up the fields	 * p->current_pdu_len, p->current_pdu_sent, p->data_sent_length	 * and stores the outgoing PDU in p->current_pdu.	 */	if(!create_next_pdu(p)) {		DEBUG(0,("read_from_pipe: %s: create_next_pdu failed.\n", p->name));		return -1;	}	data_returned = MIN(n, p->out_data.current_pdu_len);	memcpy( data, p->out_data.current_pdu, (size_t)data_returned);	p->out_data.current_pdu_sent += (uint32)data_returned;  out:	(*is_data_outstanding) = p->out_data.current_pdu_len > n;	return data_returned;}/**************************************************************************** Wait device state on a pipe. Exactly what this is for is unknown...****************************************************************************/BOOL wait_rpc_pipe_hnd_state(smb_np_struct *p, uint16 priority){	if (p == NULL) {		return False;	}	if (p->open) {		DEBUG(3,("wait_rpc_pipe_hnd_state: Setting pipe wait state priority=%x on pipe (name=%s)\n",		         priority, p->name));		p->priority = priority;				return True;	} 	DEBUG(3,("wait_rpc_pipe_hnd_state: Error setting pipe wait state priority=%x (name=%s)\n",		 priority, p->name));	return False;}/**************************************************************************** Set device state on a pipe. Exactly what this is for is unknown...****************************************************************************/BOOL set_rpc_pipe_hnd_state(smb_np_struct *p, uint16 device_state){	if (p == NULL) {		return False;	}	if (p->open) {		DEBUG(3,("set_rpc_pipe_hnd_state: Setting pipe device state=%x on pipe (name=%s)\n",		         device_state, p->name));		p->device_state = device_state;				return True;	} 	DEBUG(3,("set_rpc_pipe_hnd_state: Error setting pipe device state=%x (name=%s)\n",		 device_state, p->name));	return False;}/**************************************************************************** Close an rpc pipe.****************************************************************************/BOOL close_rpc_pipe_hnd(smb_np_struct *p){	if (!p) {		DEBUG(0,("Invalid pipe in close_rpc_pipe_hnd\n"));		return False;	}	p->namedpipe_close(p->np_state);	bitmap_clear(bmap, p->pnum - pipe_handle_offset);	pipes_open--;	DEBUG(4,("closed pipe name %s pnum=%x (pipes_open=%d)\n", 		 p->name, p->pnum, pipes_open));  	DLIST_REMOVE(Pipes, p);	ZERO_STRUCTP(p);	SAFE_FREE(p);	return True;}/**************************************************************************** Close all pipes on a connection.****************************************************************************/void pipe_close_conn(connection_struct *conn){	smb_np_struct *p, *next;	for (p=Pipes;p;p=next) {		next = p->next;		if (p->conn == conn) {			close_rpc_pipe_hnd(p);		}	}}/**************************************************************************** Close an rpc pipe.****************************************************************************/static BOOL close_internal_rpc_pipe_hnd(void *np_conn){	pipes_struct *p = (pipes_struct *)np_conn;	if (!p) {		DEBUG(0,("Invalid pipe in close_internal_rpc_pipe_hnd\n"));		return False;	}	prs_mem_free(&p->out_data.rdata);	prs_mem_free(&p->in_data.data);	if (p->auth.auth_data_free_func) {		(*p->auth.auth_data_free_func)(&p->auth);	}	if (p->mem_ctx) {		talloc_destroy(p->mem_ctx);	}	if (p->pipe_state_mem_ctx) {		talloc_destroy(p->pipe_state_mem_ctx);	}	free_pipe_rpc_context( p->contexts );	/* Free the handles database. */	close_policy_by_pipe(p);	delete_nt_token(&p->pipe_user.nt_user_token);	data_blob_free(&p->session_key);	SAFE_FREE(p->pipe_user.groups);	DLIST_REMOVE(InternalPipes, p);	ZERO_STRUCTP(p);	SAFE_FREE(p);		return True;}/**************************************************************************** Find an rpc pipe given a pipe handle in a buffer and an offset.****************************************************************************/smb_np_struct *get_rpc_pipe_p(char *buf, int where){	int pnum = SVAL(buf,where);	if (chain_p) {		return chain_p;	}	return get_rpc_pipe(pnum);}/**************************************************************************** Find an rpc pipe given a pipe handle.****************************************************************************/smb_np_struct *get_rpc_pipe(int pnum){	smb_np_struct *p;	DEBUG(4,("search for pipe pnum=%x\n", pnum));	for (p=Pipes;p;p=p->next) {		DEBUG(5,("pipe name %s pnum=%x (pipes_open=%d)\n", 		          p->name, p->pnum, pipes_open));  	}	for (p=Pipes;p;p=p->next) {		if (p->pnum == pnum) {			chain_p = p;			return p;		}	}	return NULL;}

⌨️ 快捷键说明

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