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

📄 nttrans.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*   Unix SMB/CIFS implementation.   SMB NT transaction handling   Copyright (C) Jeremy Allison			1994-1998   Copyright (C) Stefan (metze) Metzmacher	2003   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.*/#include "includes.h"extern int max_send;extern enum protocol_types Protocol;extern int smb_read_error;extern struct current_user current_user;static const char *known_nt_pipes[] = {	"\\LANMAN",	"\\srvsvc",	"\\samr",	"\\wkssvc",	"\\NETLOGON",	"\\ntlsa",	"\\ntsvcs",	"\\lsass",	"\\lsarpc",	"\\winreg",	"\\spoolss",	"\\netdfs",	"\\rpcecho",        "\\svcctl",	"\\eventlog",	"\\unixinfo",	NULL};static char *nttrans_realloc(char **ptr, size_t size){	char *tptr = NULL;	if (ptr==NULL) {		smb_panic("nttrans_realloc() called with NULL ptr\n");	}			tptr = SMB_REALLOC(*ptr, size);	if(tptr == NULL) {		*ptr = NULL;		return NULL;	}	memset(tptr,'\0',size);	*ptr = tptr;	return tptr;}/**************************************************************************** Send the required number of replies back. We assume all fields other than the data fields are set correctly for the type of call. HACK ! Always assumes smb_setup field is zero.****************************************************************************/static int send_nt_replies(char *inbuf, char *outbuf, int bufsize, NTSTATUS nt_error, char *params,                           int paramsize, char *pdata, int datasize){	int data_to_send = datasize;	int params_to_send = paramsize;	int useable_space;	char *pp = params;	char *pd = pdata;	int params_sent_thistime, data_sent_thistime, total_sent_thistime;	int alignment_offset = 3;	int data_alignment_offset = 0;	/*	 * Initially set the wcnt area to be 18 - this is true for all	 * transNT replies.	 */	set_message(outbuf,18,0,True);	if (NT_STATUS_V(nt_error)) {		ERROR_NT(nt_error);	}	/* 	 * If there genuinely are no parameters or data to send just send	 * the empty packet.	 */	if(params_to_send == 0 && data_to_send == 0) {		show_msg(outbuf);		if (!send_smb(smbd_server_fd(),outbuf)) {			exit_server("send_nt_replies: send_smb failed.");		}		return 0;	}	/*	 * When sending params and data ensure that both are nicely aligned.	 * Only do this alignment when there is also data to send - else	 * can cause NT redirector problems.	 */	if (((params_to_send % 4) != 0) && (data_to_send != 0)) {		data_alignment_offset = 4 - (params_to_send % 4);	}	/* 	 * Space is bufsize minus Netbios over TCP header minus SMB header.	 * The alignment_offset is to align the param bytes on a four byte	 * boundary (2 bytes for data len, one byte pad). 	 * NT needs this to work correctly.	 */	useable_space = bufsize - ((smb_buf(outbuf)+				alignment_offset+data_alignment_offset) -				outbuf);	/*	 * useable_space can never be more than max_send minus the	 * alignment offset.	 */	useable_space = MIN(useable_space,				max_send - (alignment_offset+data_alignment_offset));	while (params_to_send || data_to_send) {		/*		 * Calculate whether we will totally or partially fill this packet.		 */		total_sent_thistime = params_to_send + data_to_send +					alignment_offset + data_alignment_offset;		/* 		 * We can never send more than useable_space.		 */		total_sent_thistime = MIN(total_sent_thistime, useable_space);		set_message(outbuf, 18, total_sent_thistime, True);		/*		 * Set total params and data to be sent.		 */		SIVAL(outbuf,smb_ntr_TotalParameterCount,paramsize);		SIVAL(outbuf,smb_ntr_TotalDataCount,datasize);		/* 		 * Calculate how many parameters and data we can fit into		 * this packet. Parameters get precedence.		 */		params_sent_thistime = MIN(params_to_send,useable_space);		data_sent_thistime = useable_space - params_sent_thistime;		data_sent_thistime = MIN(data_sent_thistime,data_to_send);		SIVAL(outbuf,smb_ntr_ParameterCount,params_sent_thistime);		if(params_sent_thistime == 0) {			SIVAL(outbuf,smb_ntr_ParameterOffset,0);			SIVAL(outbuf,smb_ntr_ParameterDisplacement,0);		} else {			/*			 * smb_ntr_ParameterOffset is the offset from the start of the SMB header to the			 * parameter bytes, however the first 4 bytes of outbuf are			 * the Netbios over TCP header. Thus use smb_base() to subtract			 * them from the calculation.			 */			SIVAL(outbuf,smb_ntr_ParameterOffset,				((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));			/* 			 * Absolute displacement of param bytes sent in this packet.			 */			SIVAL(outbuf,smb_ntr_ParameterDisplacement,pp - params);		}		/*		 * Deal with the data portion.		 */		SIVAL(outbuf,smb_ntr_DataCount, data_sent_thistime);		if(data_sent_thistime == 0) {			SIVAL(outbuf,smb_ntr_DataOffset,0);			SIVAL(outbuf,smb_ntr_DataDisplacement, 0);		} else {			/*			 * The offset of the data bytes is the offset of the			 * parameter bytes plus the number of parameters being sent this time.			 */			SIVAL(outbuf,smb_ntr_DataOffset,((smb_buf(outbuf)+alignment_offset) -				smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);				SIVAL(outbuf,smb_ntr_DataDisplacement, pd - pdata);		}		/* 		 * Copy the param bytes into the packet.		 */		if(params_sent_thistime) {			memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);		}		/*		 * Copy in the data bytes		 */		if(data_sent_thistime) {			memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+				data_alignment_offset,pd,data_sent_thistime);		}    		DEBUG(9,("nt_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",			params_sent_thistime, data_sent_thistime, useable_space));		DEBUG(9,("nt_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",			params_to_send, data_to_send, paramsize, datasize));    		/* Send the packet */		show_msg(outbuf);		if (!send_smb(smbd_server_fd(),outbuf)) {			exit_server("send_nt_replies: send_smb failed.");		}    		pp += params_sent_thistime;		pd += data_sent_thistime;    		params_to_send -= params_sent_thistime;		data_to_send -= data_sent_thistime;		/*		 * Sanity check		 */		if(params_to_send < 0 || data_to_send < 0) {			DEBUG(0,("send_nt_replies failed sanity check pts = %d, dts = %d\n!!!",				params_to_send, data_to_send));			return -1;		}	} 	return 0;}/**************************************************************************** Is it an NTFS stream name ?****************************************************************************/BOOL is_ntfs_stream_name(const char *fname){	if (lp_posix_pathnames()) {		return False;	}	return (strchr_m(fname, ':') != NULL) ? True : False;}/**************************************************************************** Save case statics.****************************************************************************/static BOOL saved_case_sensitive;static BOOL saved_case_preserve;static BOOL saved_short_case_preserve;/**************************************************************************** Save case semantics.****************************************************************************/static void set_posix_case_semantics(connection_struct *conn, uint32 file_attributes){	if(!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) {		return;	}	saved_case_sensitive = conn->case_sensitive;	saved_case_preserve = conn->case_preserve;	saved_short_case_preserve = conn->short_case_preserve;	/* Set to POSIX. */	conn->case_sensitive = True;	conn->case_preserve = True;	conn->short_case_preserve = True;}/**************************************************************************** Restore case semantics.****************************************************************************/static void restore_case_semantics(connection_struct *conn, uint32 file_attributes){	if(!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) {		return;	}	conn->case_sensitive = saved_case_sensitive;	conn->case_preserve = saved_case_preserve;	conn->short_case_preserve = saved_short_case_preserve;}/**************************************************************************** Reply to an NT create and X call on a pipe.****************************************************************************/static int nt_open_pipe(char *fname, connection_struct *conn,			char *inbuf, char *outbuf, int *ppnum){	smb_np_struct *p = NULL;	uint16 vuid = SVAL(inbuf, smb_uid);	int i;	DEBUG(4,("nt_open_pipe: Opening pipe %s.\n", fname));    	/* See if it is one we want to handle. */	if (lp_disable_spoolss() && strequal(fname, "\\spoolss")) {		return(ERROR_BOTH(NT_STATUS_OBJECT_NAME_NOT_FOUND,ERRDOS,ERRbadpipe));	}	for( i = 0; known_nt_pipes[i]; i++ ) {		if( strequal(fname,known_nt_pipes[i])) {			break;		}	}    	if ( known_nt_pipes[i] == NULL ) {		return(ERROR_BOTH(NT_STATUS_OBJECT_NAME_NOT_FOUND,ERRDOS,ERRbadpipe));	}    	/* Strip \\ off the name. */	fname++;    	DEBUG(3,("nt_open_pipe: Known pipe %s opening.\n", fname));	p = open_rpc_pipe_p(fname, conn, vuid);	if (!p) {		return(ERROR_DOS(ERRSRV,ERRnofids));	}	*ppnum = p->pnum;	return 0;}/**************************************************************************** Reply to an NT create and X call for pipes.****************************************************************************/static int do_ntcreate_pipe_open(connection_struct *conn,			 char *inbuf,char *outbuf,int length,int bufsize){	pstring fname;	int ret;	int pnum = -1;	char *p = NULL;	srvstr_pull_buf(inbuf, fname, smb_buf(inbuf), sizeof(fname), STR_TERMINATE);	if ((ret = nt_open_pipe(fname, conn, inbuf, outbuf, &pnum)) != 0) {		return ret;	}	/*	 * Deal with pipe return.	 */  	set_message(outbuf,34,0,True);	p = outbuf + smb_vwv2;	p++;	SSVAL(p,0,pnum);	p += 2;	SIVAL(p,0,FILE_WAS_OPENED);	p += 4;	p += 32;	SIVAL(p,0,FILE_ATTRIBUTE_NORMAL); /* File Attributes. */	p += 20;	/* File type. */	SSVAL(p,0,FILE_TYPE_MESSAGE_MODE_PIPE);	/* Device state. */	SSVAL(p,2, 0x5FF); /* ? */	DEBUG(5,("do_ntcreate_pipe_open: open pipe = %s\n", fname));	return chain_reply(inbuf,outbuf,length,bufsize);}/**************************************************************************** Reply to an NT create and X call for a quota file.****************************************************************************/int reply_ntcreate_and_X_quota(connection_struct *conn,				char *inbuf,				char *outbuf,				int length,				int bufsize,				enum FAKE_FILE_TYPE fake_file_type,				const char *fname){	int result;	char *p;	uint32 desired_access = IVAL(inbuf,smb_ntcreate_DesiredAccess);	files_struct *fsp = open_fake_file(conn, fake_file_type, fname, desired_access);	if (!fsp) {		return ERROR_NT(NT_STATUS_ACCESS_DENIED);	}	set_message(outbuf,34,0,True);		p = outbuf + smb_vwv2;		/* SCVAL(p,0,NO_OPLOCK_RETURN); */	p++;	SSVAL(p,0,fsp->fnum);#if 0	p += 2;	SIVAL(p,0,smb_action);	p += 4;		/* Create time. */  	put_long_date(p,c_time);	p += 8;	put_long_date(p,sbuf.st_atime); /* access time */	p += 8;	put_long_date(p,sbuf.st_mtime); /* write time */	p += 8;	put_long_date(p,sbuf.st_mtime); /* change time */	p += 8;	SIVAL(p,0,fattr); /* File Attributes. */	p += 4;	SOFF_T(p, 0, get_allocation_size(conn,fsp,&sbuf));	p += 8;	SOFF_T(p,0,file_len);	p += 8;	if (flags & EXTENDED_RESPONSE_REQUIRED)		SSVAL(p,2,0x7);	p += 4;	SCVAL(p,0,fsp->is_directory ? 1 : 0);#endif	DEBUG(5,("reply_ntcreate_and_X_quota: fnum = %d, open name = %s\n", fsp->fnum, fsp->fsp_name));	result = chain_reply(inbuf,outbuf,length,bufsize);	return result;}/**************************************************************************** Reply to an NT create and X call.****************************************************************************/int reply_ntcreate_and_X(connection_struct *conn,			 char *inbuf,char *outbuf,int length,int bufsize){  	int result;	pstring fname;

⌨️ 快捷键说明

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