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

📄 nttrans.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
			restore_case_semantics(conn, file_attributes);			return ERROR_NT(status);		}		fsp->access_mask = saved_access_mask; 	}		if (ea_len && (info == FILE_WAS_CREATED)) {		status = set_ea(conn, fsp, fname, ea_list);		talloc_destroy(ctx);		if (!NT_STATUS_IS_OK(status)) {			close_file(fsp,False);			restore_case_semantics(conn, file_attributes);			return ERROR_NT(status);		}	}	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);		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(params,12);#ifdef LARGE_SMB_OFF_T		allocation_size |= (((SMB_BIG_UINT)IVAL(params,16)) << 32);#endif		if (allocation_size && (allocation_size > file_len)) {			fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);			if (fsp->is_directory) {				close_file(fsp,False);				/* 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);				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;	}	/* Realloc the size of parameters and data we will return */	params = nttrans_realloc(ppparams, 69);	if(params == NULL) {		return ERROR_DOS(ERRDOS,ERRnomem);	}	p = params;	if (extended_oplock_granted) {		SCVAL(p,0, BATCH_OPLOCK_RETURN);	} else if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type)) {		SCVAL(p,0, LEVEL_II_OPLOCK_RETURN);	} else {		SCVAL(p,0,NO_OPLOCK_RETURN);	}		p += 2;	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 += 8;	/* 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,("call_nt_transact_create: open name = %s\n", fname));	/* Send the required number of replies */	send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, params, 69, *ppdata, 0);	return -1;}/**************************************************************************** Reply to a NT CANCEL request.****************************************************************************/int reply_ntcancel(connection_struct *conn,		   char *inbuf,char *outbuf,int length,int bufsize){	/*	 * Go through and cancel any pending change notifies.	 */		int mid = SVAL(inbuf,smb_mid);	START_PROFILE(SMBntcancel);	remove_pending_change_notify_requests_by_mid(mid);	remove_pending_lock_requests_by_mid(mid);	srv_cancel_sign_response(mid);		DEBUG(3,("reply_ntcancel: cancel called on mid = %d.\n", mid));	END_PROFILE(SMBntcancel);	return(-1);}/**************************************************************************** Copy a file.****************************************************************************/static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *newname, uint32 attrs){	BOOL bad_path_oldname = False;	BOOL bad_path_newname = False;	SMB_STRUCT_STAT sbuf1, sbuf2;	pstring last_component_oldname;	pstring last_component_newname;	files_struct *fsp1,*fsp2;	uint32 fattr;	int info;	SMB_OFF_T ret=-1;	int close_ret;	NTSTATUS status = NT_STATUS_OK;	ZERO_STRUCT(sbuf1);	ZERO_STRUCT(sbuf2);	/* No wildcards. */	if (ms_has_wild(newname) || ms_has_wild(oldname)) {		return NT_STATUS_OBJECT_PATH_SYNTAX_BAD;	}	if (!CAN_WRITE(conn))		return NT_STATUS_MEDIA_WRITE_PROTECTED;	unix_convert(oldname,conn,last_component_oldname,&bad_path_oldname,&sbuf1);	if (bad_path_oldname) {		return NT_STATUS_OBJECT_PATH_NOT_FOUND;	}	/* Quick check for "." and ".." */	if (last_component_oldname[0] == '.') {		if (!last_component_oldname[1] || (last_component_oldname[1] == '.' && !last_component_oldname[2])) {			return NT_STATUS_OBJECT_NAME_INVALID;		}	}        /* Source must already exist. */	if (!VALID_STAT(sbuf1)) {		return NT_STATUS_OBJECT_NAME_NOT_FOUND;	}	if (!check_name(oldname,conn)) {		return NT_STATUS_ACCESS_DENIED;	}	/* Ensure attributes match. */	fattr = dos_mode(conn,oldname,&sbuf1);	if ((fattr & ~attrs) & (aHIDDEN | aSYSTEM)) {		return NT_STATUS_NO_SUCH_FILE;	}	unix_convert(newname,conn,last_component_newname,&bad_path_newname,&sbuf2);	if (bad_path_newname) {		return NT_STATUS_OBJECT_PATH_NOT_FOUND;	}	/* Quick check for "." and ".." */	if (last_component_newname[0] == '.') {		if (!last_component_newname[1] || (last_component_newname[1] == '.' && !last_component_newname[2])) {			return NT_STATUS_OBJECT_NAME_INVALID;		}	}	/* Disallow if newname already exists. */	if (VALID_STAT(sbuf2)) {		return NT_STATUS_OBJECT_NAME_COLLISION;	}	if (!check_name(newname,conn)) {		return NT_STATUS_ACCESS_DENIED;	}	/* No links from a directory. */	if (S_ISDIR(sbuf1.st_mode)) {		return NT_STATUS_FILE_IS_A_DIRECTORY;	}	/* Ensure this is within the share. */	if (!reduce_name(conn, oldname) != 0) {		return NT_STATUS_ACCESS_DENIED;	}	DEBUG(10,("copy_internals: doing file copy %s to %s\n", oldname, newname));        fsp1 = open_file_ntcreate(conn,oldname,&sbuf1,			FILE_READ_DATA, /* Read-only. */			0, /* No sharing. */			FILE_OPEN,			0, /* No create options. */			FILE_ATTRIBUTE_NORMAL,			INTERNAL_OPEN_ONLY,			&info);	if (!fsp1) {		status = get_saved_ntstatus();		if (NT_STATUS_IS_OK(status)) {			status = NT_STATUS_ACCESS_DENIED;		}		set_saved_ntstatus(NT_STATUS_OK);		return status;	}        fsp2 = open_file_ntcreate(conn,newname,&sbuf2,			FILE_WRITE_DATA, /* Read-only. */			0, /* No sharing. */			FILE_CREATE,			0, /* No create options. */			fattr,			INTERNAL_OPEN_ONLY,			&info);	if (!fsp2) {		status = get_saved_ntstatus();		if (NT_STATUS_IS_OK(status)) {			status = NT_STATUS_ACCESS_DENIED;		}		set_saved_ntstatus(NT_STATUS_OK);		close_file(fsp1,False);		return status;	}	if (sbuf1.st_size) {		ret = vfs_transfer_file(fsp1, fsp2, sbuf1.st_size);	}	/*	 * As we are opening fsp1 read-only we only expect	 * an error on close on fsp2 if we are out of space.	 * Thus we don't look at the error return from the	 * close of fsp1.	 */	close_file(fsp1,False);	/* Ensure the modtime is set correctly on the destination file. */	fsp_set_pending_modtime(fsp2, sbuf1.st_mtime);	close_ret = close_file(fsp2,False);	/* Grrr. We have to do this as open_file_shared1 adds aARCH when it	   creates the file. This isn't the correct thing to do in the copy case. JRA */	file_set_dosmode(conn, newname, fattr, &sbuf2, True);	if (ret < (SMB_OFF_T)sbuf1.st_size) {		return NT_STATUS_DISK_FULL;	}	if (close_ret != 0) {		status = map_nt_error_from_unix(close_ret);		DEBUG(3,("copy_internals: Error %s copy file %s to %s\n",			nt_errstr(status), oldname, newname));	}	return status;}/**************************************************************************** Reply to a NT rename request.****************************************************************************/int reply_ntrename(connection_struct *conn,		   char *inbuf,char *outbuf,int length,int bufsize){	int outsize = 0;	pstring oldname;	pstring newname;	char *p;	NTSTATUS status;	BOOL path_contains_wcard = False;	uint32 attrs = SVAL(inbuf,smb_vwv0);	uint16 rename_type = SVAL(inbuf,smb_vwv1);	START_PROFILE(SMBntrename);	p = smb_buf(inbuf) + 1;	p += srvstr_get_path_wcard(inbuf, oldname, p, sizeof(oldname), 0, STR_TERMINATE, &status, &path_contains_wcard);	if (!NT_STATUS_IS_OK(status)) {		END_PROFILE(SMBntrename);		return ERROR_NT(status);	}	if( is_ntfs_stream_name(oldname)) {		/* Can't rename a stream. */		END_PROFILE(SMBntrename);		return ERROR_NT(NT_STATUS_ACCESS_DENIED);	}	if (ms_has_wild(oldname)) {		END_PROFILE(SMBntrename);		return ERROR_NT(NT_STATUS_OBJECT_PATH_SYNTAX_BAD);	}	p++;	p += srvstr_get_path(inbuf, newname, p, sizeof(newname), 0, STR_TERMINATE, &status);	if (!NT_STATUS_IS_OK(status)) {		END_PROFILE(SMBntrename);		return ERROR_NT(status);	}		RESOLVE_DFSPATH(oldname, conn, inbuf, outbuf);	RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);		DEBUG(3,("reply_ntrename : %s -> %s\n",oldname,newname));		switch(rename_type) {		case RENAME_FLAG_RENAME:			status = rename_internals(conn, oldname, newname, attrs, False, path_contains_wcard);			break;		case RENAME_FLAG_HARD_LINK:			status = hardlink_internals(conn, oldname, newname);			break;		case RENAME_FLAG_COPY:			if (path_contains_wcard) {				/* No wildcards. */				status = NT_STATUS_OBJECT_PATH_SYNTAX_BAD;			} else {				status = copy_internals(conn, oldname, newname, attrs);			}			break;		case RENAME_FLAG_MOVE_CLUSTER_INFORMATION:			status = NT_STATUS_INVALID_PARAMETER;			break;		default:			status = NT_STATUS_ACCESS_DENIED; /* Default error. */			break;	}	if (!NT_STATUS_IS_OK(status)) {		END_PROFILE(SMBntrename);		if (open_was_deferred(SVAL(inbuf,smb_mid))) {			/* We have re-scheduled this call. */			return -1;		}		return ERROR_NT(status);	}	/*	 * Win2k needs a changenotify request response before it will	 * update after a rename..	 */		process_pending_change_notify_queue((time_t)0);	outsize = set_message(outbuf,0,0,True);  	END_PROFILE(SMBntrename);	return(outsize);}/**************************************************************************** Reply to an unsolicited SMBNTtranss - just ignore it!****************************************************************************/int reply_nttranss(connection_struct *conn,		   char *inbuf,char *outbuf,int length,int bufsize){	START_PROFILE(SMBnttranss);	DEBUG(4,("Ignoring nttranss of length %d\n",length));	END_PROFILE(SMBnttranss);	return(-1);}/**************************************************************************** Reply to a notify change - queue the request and  don't allow a directory to be opened.****************************************************************************/static int call_nt_transact_notify_change(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, uint32 max_data_count){	char *setup = *ppsetup;	files_struct *fsp;	uint32 flags;	if(setup_count < 6) {		return ERROR_DOS(ERRDOS,ERRbadfunc);	}	fsp = file_fsp(setup,4);	flags = IVAL(setup, 0);	DEBUG(3,("call_nt_transact_notify_change\n"));	if(!fsp) {		return ERROR_DOS(ERRDOS,ERRbadfid);	}	if((!fsp->is_directory) || (conn != fsp->conn)) {		return ERROR_DOS(ERRDOS,ERRbadfid);	}	if (!change_notify_set(inbuf, fsp, conn, flags)) {		return(UNIXERROR(ERRDOS,ERRbadfid));	}	DEBUG(3,("call_nt_transact_notify_change: notify change called on directory \name = %s\n", fsp->fsp_name ));	return -1;}/**************************************************************************** Reply to an NT transact rename command.****************************************************************************/static int call_nt_transact_rename(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, uint32 max_data_count){	char *params = *ppparams;	pstring new_name;	files_struct *fsp = NULL;	BOOL replace_if_exists = False;	BOOL path_contains_wcard = False;	NTSTATUS status;        if(parameter_count < 4) {		return ERROR_DOS(ERRDOS,ERRbadfunc);	}

⌨️ 快捷键说明

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