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

📄 nttrans.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	uint32 flags = IVAL(inbuf,smb_ntcreate_Flags);	uint32 access_mask = IVAL(inbuf,smb_ntcreate_DesiredAccess);	uint32 file_attributes = IVAL(inbuf,smb_ntcreate_FileAttributes);	uint32 share_access = IVAL(inbuf,smb_ntcreate_ShareAccess);	uint32 create_disposition = IVAL(inbuf,smb_ntcreate_CreateDisposition);	uint32 create_options = IVAL(inbuf,smb_ntcreate_CreateOptions);	uint16 root_dir_fid = (uint16)IVAL(inbuf,smb_ntcreate_RootDirectoryFid);	/* Breakout the oplock request bits so we can set the	   reply bits separately. */	int oplock_request = 0;	uint32 fattr=0;	SMB_OFF_T file_len = 0;	SMB_STRUCT_STAT sbuf;	int info = 0;	BOOL bad_path = False;	files_struct *fsp=NULL;	char *p = NULL;	time_t c_time;	BOOL extended_oplock_granted = False;	NTSTATUS status;	START_PROFILE(SMBntcreateX);	DEBUG(10,("reply_ntcreateX: flags = 0x%x, access_mask = 0x%x \file_attributes = 0x%x, share_access = 0x%x, create_disposition = 0x%x \create_options = 0x%x root_dir_fid = 0x%x\n",			(unsigned int)flags,			(unsigned int)access_mask,			(unsigned int)file_attributes,			(unsigned int)share_access,			(unsigned int)create_disposition,			(unsigned int)create_options,			(unsigned int)root_dir_fid ));	/* If it's an IPC, use the pipe handler. */	if (IS_IPC(conn)) {		if (lp_nt_pipe_support()) {			END_PROFILE(SMBntcreateX);			return do_ntcreate_pipe_open(conn,inbuf,outbuf,length,bufsize);		} else {			END_PROFILE(SMBntcreateX);			return(ERROR_DOS(ERRDOS,ERRnoaccess));		}	}				if (create_options & FILE_OPEN_BY_FILE_ID) {		END_PROFILE(SMBntcreateX);		return ERROR_NT(NT_STATUS_NOT_SUPPORTED);	}	/*	 * Get the file name.	 */	if(root_dir_fid != 0) {		/*		 * This filename is relative to a directory fid.		 */		pstring rel_fname;		files_struct *dir_fsp = file_fsp(inbuf,smb_ntcreate_RootDirectoryFid);		size_t dir_name_len;		if(!dir_fsp) {			END_PROFILE(SMBntcreateX);			return(ERROR_DOS(ERRDOS,ERRbadfid));		}		if(!dir_fsp->is_directory) {			srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status);			if (!NT_STATUS_IS_OK(status)) {				END_PROFILE(SMBntcreateX);				return ERROR_NT(status);			}			/* 			 * Check to see if this is a mac fork of some kind.			 */			if( is_ntfs_stream_name(fname)) {				END_PROFILE(SMBntcreateX);				return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);			}			/*			  we need to handle the case when we get a			  relative open relative to a file and the			  pathname is blank - this is a reopen!			  (hint from demyn plantenberg)			*/			END_PROFILE(SMBntcreateX);			return(ERROR_DOS(ERRDOS,ERRbadfid));		}		/*		 * Copy in the base directory name.		 */		pstrcpy( fname, dir_fsp->fsp_name );		dir_name_len = strlen(fname);		/*		 * Ensure it ends in a '\'.		 */		if(fname[dir_name_len-1] != '\\' && fname[dir_name_len-1] != '/') {			pstrcat(fname, "/");			dir_name_len++;		}		srvstr_get_path(inbuf, rel_fname, smb_buf(inbuf), sizeof(rel_fname), 0, STR_TERMINATE, &status);		if (!NT_STATUS_IS_OK(status)) {			END_PROFILE(SMBntcreateX);			return ERROR_NT(status);		}		pstrcat(fname, rel_fname);	} else {		srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status);		if (!NT_STATUS_IS_OK(status)) {			END_PROFILE(SMBntcreateX);			return ERROR_NT(status);		}		/* 		 * Check to see if this is a mac fork of some kind.		 */		if( is_ntfs_stream_name(fname)) {			enum FAKE_FILE_TYPE fake_file_type = is_fake_file(fname);			if (fake_file_type!=FAKE_FILE_TYPE_NONE) {				/*				 * Here we go! support for changing the disk quotas --metze				 *				 * We need to fake up to open this MAGIC QUOTA file 				 * and return a valid FID.				 *				 * w2k close this file directly after openening				 * xp also tries a QUERY_FILE_INFO on the file and then close it				 */				result = reply_ntcreate_and_X_quota(conn, inbuf, outbuf, length, bufsize,								fake_file_type, fname);				END_PROFILE(SMBntcreateX);				return result;			} else {				END_PROFILE(SMBntcreateX);				return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);			}		}	}		/*	 * Now contruct the smb_open_mode value from the filename, 	 * desired access and the share access.	 */	RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);	oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;	if (oplock_request) {		oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;	}	/*	 * Ordinary file or directory.	 */			/*	 * Check if POSIX semantics are wanted.	 */			set_posix_case_semantics(conn, file_attributes);			unix_convert(fname,conn,0,&bad_path,&sbuf);	if (bad_path) {		restore_case_semantics(conn, file_attributes);		END_PROFILE(SMBntcreateX);		return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);	}	/* All file access must go through check_name() */	if (!check_name(fname,conn)) {		restore_case_semantics(conn, file_attributes);		END_PROFILE(SMBntcreateX);		return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);	}#if 0	/* This is the correct thing to do (check every time) but can_delete is	   expensive (it may have to read the parent directory permissions). So	   for now we're not doing it unless we have a strong hint the client	   is really going to delete this file. */	if (desired_access & DELETE_ACCESS) {#else	/* Setting FILE_SHARE_DELETE is the hint. */	if (lp_acl_check_permissions(SNUM(conn)) && (share_access & FILE_SHARE_DELETE)				&& (access_mask & DELETE_ACCESS)) {#endif		status = can_delete(conn, fname, file_attributes, bad_path, True);		/* We're only going to fail here if it's access denied, as that's the		   only error we care about for "can we delete this ?" questions. */		if (!NT_STATUS_IS_OK(status) && (NT_STATUS_EQUAL(status,NT_STATUS_ACCESS_DENIED) ||						 NT_STATUS_EQUAL(status,NT_STATUS_CANNOT_DELETE))) {			restore_case_semantics(conn, file_attributes);			END_PROFILE(SMBntcreateX);			return ERROR_NT(NT_STATUS_ACCESS_DENIED);		}	}	/* 	 * If it's a request for a directory open, deal with it separately.	 */	if(create_options & FILE_DIRECTORY_FILE) {		oplock_request = 0;				/* Can't open a temp directory. IFS kit test. */		if (file_attributes & FILE_ATTRIBUTE_TEMPORARY) {			END_PROFILE(SMBntcreateX);			return ERROR_NT(NT_STATUS_INVALID_PARAMETER);		}		fsp = open_directory(conn, fname, &sbuf,					access_mask,					share_access,					create_disposition,					create_options,					&info);		restore_case_semantics(conn, file_attributes);		if(!fsp) {			END_PROFILE(SMBntcreateX);			return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);		}	} else {		/*		 * Ordinary file case.		 */		/* NB. We have a potential bug here. If we		 * cause an oplock break to ourselves, then we		 * could end up processing filename related		 * SMB requests whilst we await the oplock		 * break response. As we may have changed the		 * filename case semantics to be POSIX-like,		 * this could mean a filename request could		 * fail when it should succeed. This is a rare		 * condition, but eventually we must arrange		 * to restore the correct case semantics		 * before issuing an oplock break request to		 * our client. JRA.  */		fsp = open_file_ntcreate(conn,fname,&sbuf,					access_mask,					share_access,					create_disposition,					create_options,					file_attributes,					oplock_request,					&info);		if (!fsp) { 			/* We cheat here. There are two cases we			 * care about. One is a directory rename,			 * where the NT client will attempt to			 * open the source directory for			 * DELETE access. Note that when the			 * NT client does this it does *not*			 * set the directory bit in the			 * request packet. This is translated			 * into a read/write open			 * request. POSIX states that any open			 * for write request on a directory			 * will generate an EISDIR error, so			 * we can catch this here and open a			 * pseudo handle that is flagged as a			 * directory. The second is an open			 * for a permissions read only, which			 * we handle in the open_file_stat case. JRA.			 */			if(errno == EISDIR) {				/*				 * Fail the open if it was explicitly a non-directory file.				 */				if (create_options & FILE_NON_DIRECTORY_FILE) {					restore_case_semantics(conn, file_attributes);					END_PROFILE(SMBntcreateX);					return ERROR_FORCE_NT(NT_STATUS_FILE_IS_A_DIRECTORY);				}					oplock_request = 0;				fsp = open_directory(conn, fname, &sbuf,							access_mask,							share_access,							create_disposition,							create_options,							&info);				if(!fsp) {					restore_case_semantics(conn, file_attributes);					END_PROFILE(SMBntcreateX);					return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);				}			} else {				restore_case_semantics(conn, file_attributes);				END_PROFILE(SMBntcreateX);				if (open_was_deferred(SVAL(inbuf,smb_mid))) {					/* We have re-scheduled this call. */					return -1;				}				return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);			}		} 	}			restore_case_semantics(conn, file_attributes);			file_len = sbuf.st_size;	fattr = dos_mode(conn,fname,&sbuf);	if(fattr == 0) {		fattr = FILE_ATTRIBUTE_NORMAL;	}	if (!fsp->is_directory && (fattr & aDIR)) {		close_file(fsp,False);		END_PROFILE(SMBntcreateX);		return ERROR_DOS(ERRDOS,ERRnoaccess);	} 		/* Save the requested allocation size. */	if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {		SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)IVAL(inbuf,smb_ntcreate_AllocationSize);#ifdef LARGE_SMB_OFF_T		allocation_size |= (((SMB_BIG_UINT)IVAL(inbuf,smb_ntcreate_AllocationSize + 4)) << 32);#endif		if (allocation_size && (allocation_size > (SMB_BIG_UINT)file_len)) {			fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);			if (fsp->is_directory) {				close_file(fsp,False);				END_PROFILE(SMBntcreateX);				/* Can't set allocation size on a directory. */				return ERROR_NT(NT_STATUS_ACCESS_DENIED);			}			if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {				close_file(fsp,False);				END_PROFILE(SMBntcreateX);				return ERROR_NT(NT_STATUS_DISK_FULL);			}		} else {			fsp->initial_allocation_size = smb_roundup(fsp->conn,(SMB_BIG_UINT)file_len);		}	}	/* 	 * If the caller set the extended oplock request bit	 * and we granted one (by whatever means) - set the	 * correct bit for extended oplock reply.	 */		if (oplock_request && lp_fake_oplocks(SNUM(conn))) {		extended_oplock_granted = True;	}		if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {		extended_oplock_granted = True;	}#if 0	/* W2K sends back 42 words here ! If we do the same it breaks offline sync. Go figure... ? JRA. */	set_message(outbuf,42,0,True);#else	set_message(outbuf,34,0,True);#endif		p = outbuf + smb_vwv2;		/*	 * Currently as we don't support level II oplocks we just report	 * exclusive & batch here.	 */	if (extended_oplock_granted) {		if (flags & REQUEST_BATCH_OPLOCK) {			SCVAL(p,0, BATCH_OPLOCK_RETURN);		} else {			SCVAL(p,0, EXCLUSIVE_OPLOCK_RETURN);		}	} else if (fsp->oplock_type == LEVEL_II_OPLOCK) {		SCVAL(p,0, LEVEL_II_OPLOCK_RETURN);	} else {		SCVAL(p,0,NO_OPLOCK_RETURN);	}		p++;	SSVAL(p,0,fsp->fnum);	p += 2;	if ((create_disposition == FILE_SUPERSEDE) && (info == FILE_WAS_OVERWRITTEN)) {		SIVAL(p,0,FILE_WAS_SUPERSEDED);	} else {		SIVAL(p,0,info);	}	p += 4;		/* Create time. */  	c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));	if (lp_dos_filetime_resolution(SNUM(conn))) {		c_time &= ~1;		sbuf.st_atime &= ~1;		sbuf.st_mtime &= ~1;		sbuf.st_mtime &= ~1;	}	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);	DEBUG(5,("reply_ntcreate_and_X: fnum = %d, open name = %s\n", fsp->fnum, fsp->fsp_name));	result = chain_reply(inbuf,outbuf,length,bufsize);	END_PROFILE(SMBntcreateX);	return result;}/**************************************************************************** Reply to a NT_TRANSACT_CREATE call to open a pipe.****************************************************************************/static int do_nt_transact_create_pipe( connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,                                  char **ppsetup, uint32 setup_count,				  char **ppparams, uint32 parameter_count,				  char **ppdata, uint32 data_count){	pstring fname;	char *params = *ppparams;	int ret;	int pnum = -1;	char *p = NULL;	NTSTATUS status;	/*	 * Ensure minimum number of parameters sent.	 */	if(parameter_count < 54) {		DEBUG(0,("do_nt_transact_create_pipe - insufficient parameters (%u)\n", (unsigned int)parameter_count));		return ERROR_DOS(ERRDOS,ERRnoaccess);	}	srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status);	if (!NT_STATUS_IS_OK(status)) {		return ERROR_NT(status);	}

⌨️ 快捷键说明

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