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

📄 open.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
		DEBUG(0,("validate_my_share_entries: PANIC : %s\n",			 share_mode_str(num, share_entry) ));		slprintf(str, sizeof(str)-1, "validate_my_share_entries: "			 "file %s, oplock_type = 0x%x, op_type = 0x%x\n",			 fsp->fsp_name, (unsigned int)fsp->oplock_type,			 (unsigned int)share_entry->op_type );		smb_panic(str);	}}#endifstatic BOOL is_stat_open(uint32 access_mask){	return (access_mask &&		((access_mask & ~(SYNCHRONIZE_ACCESS| FILE_READ_ATTRIBUTES|				  FILE_WRITE_ATTRIBUTES))==0) &&		((access_mask & (SYNCHRONIZE_ACCESS|FILE_READ_ATTRIBUTES|				 FILE_WRITE_ATTRIBUTES)) != 0));}/**************************************************************************** Deal with share modes Invarient: Share mode must be locked on entry and exit. Returns -1 on error, or number of share modes on success (may be zero).****************************************************************************/static NTSTATUS open_mode_check(connection_struct *conn,				const char *fname,				struct share_mode_lock *lck,				uint32 access_mask,				uint32 share_access,				uint32 create_options,				BOOL *file_existed){	int i;	if(lck->num_share_modes == 0) {		return NT_STATUS_OK;	}	*file_existed = True;		if (is_stat_open(access_mask)) {		/* Stat open that doesn't trigger oplock breaks or share mode		 * checks... ! JRA. */		return NT_STATUS_OK;	}	/* A delete on close prohibits everything */	if (lck->delete_on_close) {		return NT_STATUS_DELETE_PENDING;	}	/*	 * Check if the share modes will give us access.	 */	#if defined(DEVELOPER)	for(i = 0; i < lck->num_share_modes; i++) {		validate_my_share_entries(i, &lck->share_modes[i]);	}#endif	if (!lp_share_modes(SNUM(conn))) {		return NT_STATUS_OK;	}	/* Now we check the share modes, after any oplock breaks. */	for(i = 0; i < lck->num_share_modes; i++) {		if (!is_valid_share_mode_entry(&lck->share_modes[i])) {			continue;		}		/* someone else has a share lock on it, check to see if we can		 * too */		if (share_conflict(&lck->share_modes[i],				   access_mask, share_access)) {			return NT_STATUS_SHARING_VIOLATION;		}	}		return NT_STATUS_OK;}static BOOL is_delete_request(files_struct *fsp) {	return ((fsp->access_mask == DELETE_ACCESS) &&		(fsp->oplock_type == NO_OPLOCK));}/* * 1) No files open at all: Grant whatever the client wants. * * 2) Exclusive (or batch) oplock around: If the requested access is a delete *    request, break if the oplock around is a batch oplock. If it's another *    requested access type, break. *  * 3) Only level2 around: Grant level2 and do nothing else. */static BOOL delay_for_oplocks(struct share_mode_lock *lck, files_struct *fsp){	int i;	struct share_mode_entry *exclusive = NULL;	BOOL delay_it = False;	BOOL have_level2 = False;	if (is_stat_open(fsp->access_mask)) {		fsp->oplock_type = NO_OPLOCK;		return False;	}	if (lck->num_share_modes == 0) {		/* No files open at all: Directly grant whatever the client		 * wants. */		if (fsp->oplock_type == NO_OPLOCK) {			/* Store a level2 oplock, but don't tell the client */			fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;		}		return False;	}	for (i=0; i<lck->num_share_modes; i++) {		if (!is_valid_share_mode_entry(&lck->share_modes[i])) {			continue;		}		if (EXCLUSIVE_OPLOCK_TYPE(lck->share_modes[i].op_type)) {			SMB_ASSERT(exclusive == NULL);						exclusive = &lck->share_modes[i];		}		if (lck->share_modes[i].op_type == LEVEL_II_OPLOCK) {			have_level2 = True;		}	}	if (exclusive != NULL) { /* Found an exclusive oplock */		SMB_ASSERT(!have_level2);		delay_it = is_delete_request(fsp) ?			BATCH_OPLOCK_TYPE(exclusive->op_type) :	True;	}	if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {		/* We can at most grant level2 */		fsp->oplock_type = LEVEL_II_OPLOCK;	}	if ((fsp->oplock_type == NO_OPLOCK) && have_level2) {		/* Store a level2 oplock, but don't tell the client */		fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;	}	if (delay_it) {		BOOL ret;		char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];		DEBUG(10, ("Sending break request to PID %s\n",			   procid_str_static(&exclusive->pid)));		exclusive->op_mid = get_current_mid();		share_mode_entry_to_message(msg, exclusive);		become_root();		ret = message_send_pid(exclusive->pid, MSG_SMB_BREAK_REQUEST,				       msg, MSG_SMB_SHARE_MODE_ENTRY_SIZE, True);		unbecome_root();		if (!ret) {			DEBUG(3, ("Could not send oplock break message\n"));		}		file_free(fsp);	}	return delay_it;}static BOOL request_timed_out(struct timeval request_time,			      struct timeval timeout){	struct timeval now, end_time;	GetTimeOfDay(&now);	end_time = timeval_sum(&request_time, &timeout);	return (timeval_compare(&end_time, &now) < 0);}/**************************************************************************** Handle the 1 second delay in returning a SHARING_VIOLATION error.****************************************************************************/static void defer_open(struct share_mode_lock *lck,		       struct timeval request_time,		       struct timeval timeout,		       struct deferred_open_record *state){	uint16 mid = get_current_mid();	int i;	/* Paranoia check */	for (i=0; i<lck->num_share_modes; i++) {		struct share_mode_entry *e = &lck->share_modes[i];		if (!is_deferred_open_entry(e)) {			continue;		}		if (procid_is_me(&e->pid) && (e->op_mid == mid)) {			DEBUG(0, ("Trying to defer an already deferred "				  "request: mid=%d, exiting\n", mid));			exit_server("exiting");		}	}	/* End paranoia check */	DEBUG(10,("defer_open_sharing_error: time [%u.%06u] adding deferred "		  "open entry for mid %u\n",		  (unsigned int)request_time.tv_sec,		  (unsigned int)request_time.tv_usec,		  (unsigned int)mid));	if (!push_deferred_smb_message(mid, request_time, timeout,				       (char *)state, sizeof(*state))) {		exit_server("push_deferred_smb_message failed\n");	}	add_deferred_open(lck, mid, request_time, state->dev, state->inode);	/*	 * Push the MID of this packet on the signing queue.	 * We only do this once, the first time we push the packet	 * onto the deferred open queue, as this has a side effect	 * of incrementing the response sequence number.	 */	srv_defer_sign_response(mid);}/**************************************************************************** Set a kernel flock on a file for NFS interoperability. This requires a patch to Linux.****************************************************************************/static void kernel_flock(files_struct *fsp, uint32 share_mode){#if HAVE_KERNEL_SHARE_MODES	int kernel_mode = 0;	if (share_mode == FILE_SHARE_WRITE) {		kernel_mode = LOCK_MAND|LOCK_WRITE;	} else if (share_mode == FILE_SHARE_READ) {		kernel_mode = LOCK_MAND|LOCK_READ;	} else if (share_mode == FILE_SHARE_NONE) {		kernel_mode = LOCK_MAND;	}	if (kernel_mode) {		flock(fsp->fh->fd, kernel_mode);	}#endif	;}/**************************************************************************** On overwrite open ensure that the attributes match.****************************************************************************/static BOOL open_match_attributes(connection_struct *conn,				const char *path,				uint32 old_dos_attr,				uint32 new_dos_attr,				mode_t existing_unx_mode,				mode_t new_unx_mode,				mode_t *returned_unx_mode){	uint32 noarch_old_dos_attr, noarch_new_dos_attr;	noarch_old_dos_attr = (old_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);	noarch_new_dos_attr = (new_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);	if((noarch_old_dos_attr == 0 && noarch_new_dos_attr != 0) || 	   (noarch_old_dos_attr != 0 && ((noarch_old_dos_attr & noarch_new_dos_attr) == noarch_old_dos_attr))) {		*returned_unx_mode = new_unx_mode;	} else {		*returned_unx_mode = (mode_t)0;	}	DEBUG(10,("open_match_attributes: file %s old_dos_attr = 0x%x, "		  "existing_unx_mode = 0%o, new_dos_attr = 0x%x "		  "returned_unx_mode = 0%o\n",		  path,		  (unsigned int)old_dos_attr,		  (unsigned int)existing_unx_mode,		  (unsigned int)new_dos_attr,		  (unsigned int)*returned_unx_mode ));	/* If we're mapping SYSTEM and HIDDEN ensure they match. */	if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {		if ((old_dos_attr & FILE_ATTRIBUTE_SYSTEM) &&		    !(new_dos_attr & FILE_ATTRIBUTE_SYSTEM)) {			return False;		}	}	if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {		if ((old_dos_attr & FILE_ATTRIBUTE_HIDDEN) &&		    !(new_dos_attr & FILE_ATTRIBUTE_HIDDEN)) {			return False;		}	}	return True;}/**************************************************************************** Special FCB or DOS processing in the case of a sharing violation. Try and find a duplicated file handle.****************************************************************************/static files_struct *fcb_or_dos_open(connection_struct *conn,				     const char *fname, SMB_DEV_T dev,				     SMB_INO_T inode,				     uint32 access_mask,				     uint32 share_access,				     uint32 create_options){	files_struct *fsp;	files_struct *dup_fsp;	DEBUG(5,("fcb_or_dos_open: attempting old open semantics for "		 "file %s.\n", fname ));	for(fsp = file_find_di_first(dev, inode); fsp;	    fsp = file_find_di_next(fsp)) {		DEBUG(10,("fcb_or_dos_open: checking file %s, fd = %d, "			  "vuid = %u, file_pid = %u, private_options = 0x%x "			  "access_mask = 0x%x\n", fsp->fsp_name,			  fsp->fh->fd, (unsigned int)fsp->vuid,			  (unsigned int)fsp->file_pid,			  (unsigned int)fsp->fh->private_options,			  (unsigned int)fsp->access_mask ));		if (fsp->fh->fd != -1 &&		    fsp->vuid == current_user.vuid &&		    fsp->file_pid == global_smbpid &&		    (fsp->fh->private_options & (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS |						 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) &&		    (fsp->access_mask & FILE_WRITE_DATA) &&		    strequal(fsp->fsp_name, fname)) {			DEBUG(10,("fcb_or_dos_open: file match\n"));			break;		}	}	if (!fsp) {		return NULL;	}	/* quite an insane set of semantics ... */	if (is_executable(fname) &&	    (fsp->fh->private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS)) {		DEBUG(10,("fcb_or_dos_open: file fail due to is_executable.\n"));		return NULL;	}	/* We need to duplicate this fsp. */	dup_fsp = dup_file_fsp(fsp, access_mask, share_access, create_options);	if (!dup_fsp) {		return NULL;	}	return dup_fsp;}/**************************************************************************** Open a file with a share mode - old openX method - map into NTCreate.****************************************************************************/BOOL map_open_params_to_ntcreate(const char *fname, int deny_mode, int open_func,				uint32 *paccess_mask,				uint32 *pshare_mode,				uint32 *pcreate_disposition,				uint32 *pcreate_options){	uint32 access_mask;	uint32 share_mode;	uint32 create_disposition;	uint32 create_options = 0;	DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, "		  "open_func = 0x%x\n",		  fname, (unsigned int)deny_mode, (unsigned int)open_func ));	/* Create the NT compatible access_mask. */	switch (GET_OPENX_MODE(deny_mode)) {		case DOS_OPEN_EXEC: /* Implies read-only - used to be FILE_READ_DATA */		case DOS_OPEN_RDONLY:			access_mask = FILE_GENERIC_READ;			break;		case DOS_OPEN_WRONLY:			access_mask = FILE_GENERIC_WRITE;			break;		case DOS_OPEN_RDWR:		case DOS_OPEN_FCB:			access_mask = FILE_GENERIC_READ|FILE_GENERIC_WRITE;			break;		default:			DEBUG(10,("map_open_params_to_ntcreate: bad open mode = 0x%x\n",				  (unsigned int)GET_OPENX_MODE(deny_mode)));			return False;	}	/* Create the NT compatible create_disposition. */	switch (open_func) {		case OPENX_FILE_EXISTS_FAIL|OPENX_FILE_CREATE_IF_NOT_EXIST:			create_disposition = FILE_CREATE;			break;		case OPENX_FILE_EXISTS_OPEN:			create_disposition = FILE_OPEN;			break;		case OPENX_FILE_EXISTS_OPEN|OPENX_FILE_CREATE_IF_NOT_EXIST:			create_disposition = FILE_OPEN_IF;			break;       		case OPENX_FILE_EXISTS_TRUNCATE:			create_disposition = FILE_OVERWRITE;			break;		case OPENX_FILE_EXISTS_TRUNCATE|OPENX_FILE_CREATE_IF_NOT_EXIST:			create_disposition = FILE_OVERWRITE_IF;			break;		default:			/* From samba4 - to be confirmed. */			if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_EXEC) {				create_disposition = FILE_CREATE;				break;			}			DEBUG(10,("map_open_params_to_ntcreate: bad "				  "open_func 0x%x\n", (unsigned int)open_func));			return False;	} 	/* Create the NT compatible share modes. */	switch (GET_DENY_MODE(deny_mode)) {		case DENY_ALL:			share_mode = FILE_SHARE_NONE;			break;		case DENY_WRITE:			share_mode = FILE_SHARE_READ;			break;		case DENY_READ:			share_mode = FILE_SHARE_WRITE;			break;		case DENY_NONE:			share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;			break;		case DENY_DOS:			create_options |= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS;	                if (is_executable(fname)) {				share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;			} else {				if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_RDONLY) {					share_mode = FILE_SHARE_READ;				} else {					share_mode = FILE_SHARE_NONE;				}			}			break;		case DENY_FCB:			create_options |= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB;			share_mode = FILE_SHARE_NONE;			break;		default:			DEBUG(10,("map_open_params_to_ntcreate: bad deny_mode 0x%x\n",				(unsigned int)GET_DENY_MODE(deny_mode) ));			return False;	}	DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, "		  "share_mode = 0x%x, create_disposition = 0x%x, "		  "create_options = 0x%x\n",		  fname,		  (unsigned int)access_mask,		  (unsigned int)share_mode,		  (unsigned int)create_disposition,		  (unsigned int)create_options ));	if (paccess_mask) {		*paccess_mask = access_mask;	}	if (pshare_mode) {		*pshare_mode = share_mode;	}	if (pcreate_disposition) {		*pcreate_disposition = create_disposition;	}	if (pcreate_options) {		*pcreate_options = create_options;	}

⌨️ 快捷键说明

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