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

📄 open.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
		inode = fsp->inode;		lck = get_share_mode_lock(NULL, dev, inode,					conn->connectpath,					fname);		if (lck == NULL) {			DEBUG(0, ("open_file_ntcreate: Could not get share mode lock for %s\n", fname));			fd_close(conn, fsp);			file_free(fsp);			set_saved_ntstatus(NT_STATUS_SHARING_VIOLATION);			return NULL;		}		status = open_mode_check(conn, fname, lck,					 access_mask, share_access,					 create_options, &file_existed);		if (!NT_STATUS_IS_OK(status)) {			struct deferred_open_record state;			fd_close(conn, fsp);			file_free(fsp);			state.delayed_for_oplocks = False;			state.dev = dev;			state.inode = inode;			/* Do it all over again immediately. In the second			 * round we will find that the file existed and handle			 * the DELETE_PENDING and FCB cases correctly. No need			 * to duplicate the code here. Essentially this is a			 * "goto top of this function", but don't tell			 * anybody... */			defer_open(lck, request_time, timeval_zero(),				   &state);			talloc_free(lck);			return NULL;		}		/*		 * We exit this block with the share entry *locked*.....		 */	}	SMB_ASSERT(lck != NULL);	/* note that we ignore failure for the following. It is           basically a hack for NFS, and NFS will never set one of           these only read them. Nobody but Samba can ever set a deny           mode and we have already checked our more authoritative           locking database for permission to set this deny mode. If           the kernel refuses the operations then the kernel is wrong */	kernel_flock(fsp, share_access);	/*	 * At this point onwards, we can guarentee that the share entry	 * is locked, whether we created the file or not, and that the	 * deny mode is compatible with all current opens.	 */	/*	 * If requested, truncate the file.	 */	if (flags2&O_TRUNC) {		/*		 * We are modifing the file after open - update the stat		 * struct..		 */		if ((SMB_VFS_FTRUNCATE(fsp,fsp->fh->fd,0) == -1) ||		    (SMB_VFS_FSTAT(fsp,fsp->fh->fd,psbuf)==-1)) {			talloc_free(lck);			fd_close(conn,fsp);			file_free(fsp);			return NULL;		}	}	/* Record the options we were opened with. */	fsp->share_access = share_access;	fsp->fh->private_options = create_options;	fsp->access_mask = access_mask;	if (file_existed) {		if (!(flags2 & O_TRUNC)) {			info = FILE_WAS_OPENED;		} else {			info = FILE_WAS_OVERWRITTEN;		}	} else {		info = FILE_WAS_CREATED;		/* Change the owner if required. */		if (lp_inherit_owner(SNUM(conn))) {			change_owner_to_parent(conn, fsp, fsp->fsp_name,					       psbuf);		}	}	if (pinfo) {		*pinfo = info;	}	/* 	 * Setup the oplock info in both the shared memory and	 * file structs.	 */	if ((fsp->oplock_type != NO_OPLOCK) &&	    (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK)) {		if (!set_file_oplock(fsp, fsp->oplock_type)) {			/* Could not get the kernel oplock */			fsp->oplock_type = NO_OPLOCK;		}	}	set_share_mode(lck, fsp, 0, fsp->oplock_type);	if (create_options & FILE_DELETE_ON_CLOSE) {		uint32 dosattr= existing_dos_attributes;		NTSTATUS result;		if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED ||				info == FILE_WAS_SUPERSEDED) {			dosattr = new_dos_attributes;		}		result = can_set_delete_on_close(fsp, True, dosattr);		if (!NT_STATUS_IS_OK(result)) {			/* Remember to delete the mode we just added. */			del_share_mode(lck, fsp);			talloc_free(lck);			fd_close(conn,fsp);			file_free(fsp);			set_saved_ntstatus(result);			return NULL;		}		lck->delete_on_close = True;		lck->modified = True;	}		if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED ||				info == FILE_WAS_SUPERSEDED) {		/* Files should be initially set as archive */		if (lp_map_archive(SNUM(conn)) ||		    lp_store_dos_attributes(SNUM(conn))) {			file_set_dosmode(conn, fname,					 new_dos_attributes | aARCH, NULL,					 True);		}	}	/*	 * Take care of inherited ACLs on created files - if default ACL not	 * selected.	 */	if (!file_existed && !def_acl) {		int saved_errno = errno; /* We might get ENOSYS in the next					  * call.. */		if (SMB_VFS_FCHMOD_ACL(fsp, fsp->fh->fd, unx_mode) == -1		    && errno == ENOSYS) {			errno = saved_errno; /* Ignore ENOSYS */		}	} else if (new_unx_mode) {		int ret = -1;		/* Attributes need changing. File already existed. */		{			int saved_errno = errno; /* We might get ENOSYS in the						  * next call.. */			ret = SMB_VFS_FCHMOD_ACL(fsp, fsp->fh->fd,						 new_unx_mode);			if (ret == -1 && errno == ENOSYS) {				errno = saved_errno; /* Ignore ENOSYS */			} else {				DEBUG(5, ("open_file_shared: reset "					  "attributes of file %s to 0%o\n",					fname, (unsigned int)new_unx_mode));				ret = 0; /* Don't do the fchmod below. */			}		}		if ((ret == -1) &&		    (SMB_VFS_FCHMOD(fsp, fsp->fh->fd, new_unx_mode) == -1))			DEBUG(5, ("open_file_shared: failed to reset "				  "attributes of file %s to 0%o\n",				fname, (unsigned int)new_unx_mode));	}	/* If this is a successful open, we must remove any deferred open	 * records. */	del_deferred_open_entry(lck, mid);	talloc_free(lck);	conn->num_files_open++;	return fsp;}/**************************************************************************** Open a file for for write to ensure that we can fchmod it.****************************************************************************/files_struct *open_file_fchmod(connection_struct *conn, const char *fname,			       SMB_STRUCT_STAT *psbuf){	files_struct *fsp = NULL;	BOOL fsp_open;	if (!VALID_STAT(*psbuf)) {		return NULL;	}	fsp = file_new(conn);	if(!fsp) {		return NULL;	}	/* note! we must use a non-zero desired access or we don't get           a real file descriptor. Oh what a twisted web we weave. */	fsp_open = open_file(fsp,conn,fname,psbuf,O_WRONLY,0,FILE_WRITE_DATA);	/* 	 * This is not a user visible file open.	 * Don't set a share mode and don't increment	 * the conn->num_files_open.	 */	if (!fsp_open) {		file_free(fsp);		return NULL;	}	return fsp;}/**************************************************************************** Close the fchmod file fd - ensure no locks are lost.****************************************************************************/int close_file_fchmod(files_struct *fsp){	int ret = fd_close(fsp->conn, fsp);	file_free(fsp);	return ret;}/**************************************************************************** Open a directory from an NT SMB call.****************************************************************************/files_struct *open_directory(connection_struct *conn,				const char *fname,				SMB_STRUCT_STAT *psbuf,				uint32 access_mask,				uint32 share_access,				uint32 create_disposition,				uint32 create_options,				int *pinfo){	files_struct *fsp = NULL;	BOOL dir_existed = VALID_STAT(*psbuf) ? True : False;	BOOL create_dir = False;	struct share_mode_lock *lck = NULL;	NTSTATUS status;	int info = 0;	DEBUG(5,("open_directory: opening directory %s, access_mask = 0x%x, "		 "share_access = 0x%x create_options = 0x%x, "		 "create_disposition = 0x%x\n",		 fname,		 (unsigned int)access_mask,		 (unsigned int)share_access,		 (unsigned int)create_options,		 (unsigned int)create_disposition));	if (is_ntfs_stream_name(fname)) {		DEBUG(0,("open_directory: %s is a stream name!\n", fname ));		set_saved_ntstatus(NT_STATUS_NOT_A_DIRECTORY);		return NULL;	}	switch( create_disposition ) {		case FILE_OPEN:			/* If directory exists open. If directory doesn't			 * exist error. */			if (!dir_existed) {				DEBUG(5,("open_directory: FILE_OPEN requested "					 "for directory %s and it doesn't "					 "exist.\n", fname ));				set_saved_ntstatus(NT_STATUS_OBJECT_NAME_NOT_FOUND);				return NULL;			}			info = FILE_WAS_OPENED;			break;		case FILE_CREATE:			/* If directory exists error. If directory doesn't			 * exist create. */			if (dir_existed) {				DEBUG(5,("open_directory: FILE_CREATE "					 "requested for directory %s and it "					 "already exists.\n", fname ));				set_saved_error_triple(ERRDOS, ERRfilexists,						       NT_STATUS_OBJECT_NAME_COLLISION);				return NULL;			}			create_dir = True;			info = FILE_WAS_CREATED;			break;		case FILE_OPEN_IF:			/* If directory exists open. If directory doesn't			 * exist create. */			if (!dir_existed) {				create_dir = True;				info = FILE_WAS_CREATED;			} else {				info = FILE_WAS_OPENED;			}			break;		case FILE_SUPERSEDE:		case FILE_OVERWRITE:		case FILE_OVERWRITE_IF:		default:			DEBUG(5,("open_directory: invalid create_disposition "				 "0x%x for directory %s\n",				 (unsigned int)create_disposition, fname));			file_free(fsp);			set_saved_ntstatus(NT_STATUS_INVALID_PARAMETER);			return NULL;	}	if (create_dir) {		/*		 * Try and create the directory.		 */		/* We know bad_path is false as it's caught earlier. */		status = mkdir_internal(conn, fname, False);		if (!NT_STATUS_IS_OK(status)) {			DEBUG(2,("open_directory: unable to create %s. "				 "Error was %s\n", fname, strerror(errno) ));			/* Ensure we return the correct NT status to the			 * client. */			set_saved_error_triple(0, 0, status);			return NULL;		}		/* Ensure we're checking for a symlink here.... */		/* We don't want to get caught by a symlink racer. */		if(SMB_VFS_LSTAT(conn,fname, psbuf) != 0) {			return NULL;		}		if(!S_ISDIR(psbuf->st_mode)) {			DEBUG(0,("open_directory: %s is not a directory !\n",				 fname ));			return NULL;		}	}	fsp = file_new(conn);	if(!fsp) {		return NULL;	}	/*	 * Setup the files_struct for it.	 */		fsp->mode = psbuf->st_mode;	fsp->inode = psbuf->st_ino;	fsp->dev = psbuf->st_dev;	fsp->vuid = current_user.vuid;	fsp->file_pid = global_smbpid;	fsp->can_lock = True;	fsp->can_read = False;	fsp->can_write = False;	fsp->share_access = share_access;	fsp->fh->private_options = create_options;	fsp->access_mask = access_mask;	fsp->print_file = False;	fsp->modified = False;	fsp->oplock_type = NO_OPLOCK;	fsp->sent_oplock_break = NO_BREAK_SENT;	fsp->is_directory = True;	fsp->is_stat = False;	string_set(&fsp->fsp_name,fname);	lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode,				conn->connectpath,				fname);	if (lck == NULL) {		DEBUG(0, ("open_directory: Could not get share mode lock for %s\n", fname));		file_free(fsp);		set_saved_ntstatus(NT_STATUS_SHARING_VIOLATION);		return NULL;	}	status = open_mode_check(conn, fname, lck,				access_mask, share_access,				create_options, &dir_existed);	if (!NT_STATUS_IS_OK(status)) {		set_saved_ntstatus(status);		talloc_free(lck);		file_free(fsp);		return NULL;	}	set_share_mode(lck, fsp, 0, NO_OPLOCK);	if (create_options & FILE_DELETE_ON_CLOSE) {		status = can_set_delete_on_close(fsp, True, 0);		if (!NT_STATUS_IS_OK(status)) {			set_saved_ntstatus(status);			talloc_free(lck);			file_free(fsp);			return NULL;		}		lck->delete_on_close = True;		lck->modified = True;	}	talloc_free(lck);	/* Change the owner if required. */	if ((info == FILE_WAS_CREATED) && lp_inherit_owner(SNUM(conn))) {		change_owner_to_parent(conn, fsp, fsp->fsp_name, psbuf);	}	if (pinfo) {		*pinfo = info;	}	conn->num_files_open++;	return fsp;}/**************************************************************************** Open a pseudo-file (no locking checks - a 'stat' open).****************************************************************************/files_struct *open_file_stat(connection_struct *conn, char *fname,			     SMB_STRUCT_STAT *psbuf){	files_struct *fsp = NULL;	if (!VALID_STAT(*psbuf))		return NULL;	/* Can't 'stat' open directories. */	if(S_ISDIR(psbuf->st_mode))		return NULL;	fsp = file_new(conn);	if(!fsp)		return NULL;	DEBUG(5,("open_file_stat: 'opening' file %s\n", fname));	/*	 * Setup the files_struct for it.	 */		fsp->mode = psbuf->st_mode;	fsp->inode = psbuf->st_ino;	fsp->dev = psbuf->st_dev;	fsp->vuid = current_user.vuid;	fsp->file_pid = global_smbpid;	fsp->can_lock = False;	fsp->can_read = False;	fsp->can_write = False;	fsp->print_file = False;	fsp->modified = False;	fsp->oplock_type = NO_OPLOCK;	fsp->sent_oplock_break = NO_BREAK_SENT;	fsp->is_directory = False;	fsp->is_stat = True;	string_set(&fsp->fsp_name,fname);	conn->num_files_open++;	return fsp;}

⌨️ 快捷键说明

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