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

📄 nttrans.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	if ((ret = nt_open_pipe(fname, conn, inbuf, outbuf, &pnum)) != 0) {		return ret;	}		/* 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;	SCVAL(p,0,NO_OPLOCK_RETURN);		p += 2;	SSVAL(p,0,pnum);	p += 2;	SIVAL(p,0,FILE_WAS_OPENED);	p += 8;		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_nt_transact_create_pipe: 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;}/**************************************************************************** Internal fn to set security descriptors.****************************************************************************/static NTSTATUS set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 security_info_sent){	prs_struct pd;	SEC_DESC *psd = NULL;	TALLOC_CTX *mem_ctx;	BOOL ret;		if (sd_len == 0 || !lp_nt_acl_support(SNUM(fsp->conn))) {		return NT_STATUS_OK;	}	/*	 * Init the parse struct we will unmarshall from.	 */	if ((mem_ctx = talloc_init("set_sd")) == NULL) {		DEBUG(0,("set_sd: talloc_init failed.\n"));		return NT_STATUS_NO_MEMORY;	}	prs_init(&pd, 0, mem_ctx, UNMARSHALL);	/*	 * Setup the prs_struct to point at the memory we just	 * allocated.	 */		prs_give_memory( &pd, data, sd_len, False);	/*	 * Finally, unmarshall from the data buffer.	 */	if(!sec_io_desc( "sd data", &psd, &pd, 1)) {		DEBUG(0,("set_sd: Error in unmarshalling security descriptor.\n"));		/*		 * Return access denied for want of a better error message..		 */ 		talloc_destroy(mem_ctx);		return NT_STATUS_NO_MEMORY;	}		if (psd->off_owner_sid==0) {		security_info_sent &= ~OWNER_SECURITY_INFORMATION;	}	if (psd->off_grp_sid==0) {		security_info_sent &= ~GROUP_SECURITY_INFORMATION;	}	if (psd->off_sacl==0) {		security_info_sent &= ~SACL_SECURITY_INFORMATION;	}	if (psd->off_dacl==0) {		security_info_sent &= ~DACL_SECURITY_INFORMATION;	}		ret = SMB_VFS_FSET_NT_ACL( fsp, fsp->fh->fd, security_info_sent, psd);		if (!ret) {		talloc_destroy(mem_ctx);		return NT_STATUS_ACCESS_DENIED;	}		talloc_destroy(mem_ctx);		return NT_STATUS_OK;}/**************************************************************************** Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.****************************************************************************/                                                                                                                             static struct ea_list *read_nttrans_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size){	struct ea_list *ea_list_head = NULL;	size_t offset = 0;	if (data_size < 4) {		return NULL;	}	while (offset + 4 <= data_size) {		size_t next_offset = IVAL(pdata,offset);		struct ea_list *tmp;		struct ea_list *eal = read_ea_list_entry(ctx, pdata + offset + 4, data_size - offset - 4, NULL);		DLIST_ADD_END(ea_list_head, eal, tmp);		if (next_offset == 0) {			break;		}		offset += next_offset;	}                                                                                                                             	return ea_list_head;}/**************************************************************************** Reply to a NT_TRANSACT_CREATE call (needs to process SD's).****************************************************************************/static int call_nt_transact_create(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){	pstring fname;	char *params = *ppparams;	char *data = *ppdata;	/* 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;	BOOL extended_oplock_granted = False;	uint32 flags;	uint32 access_mask;	uint32 file_attributes;	uint32 share_access;	uint32 create_disposition;	uint32 create_options;	uint32 sd_len;	uint32 ea_len;	uint16 root_dir_fid;	time_t c_time;	struct ea_list *ea_list = NULL;	TALLOC_CTX *ctx = NULL;	char *pdata = NULL;	NTSTATUS status;	DEBUG(5,("call_nt_transact_create\n"));	/*	 * If it's an IPC, use the pipe handler.	 */	if (IS_IPC(conn)) {		if (lp_nt_pipe_support()) {			return do_nt_transact_create_pipe(conn, inbuf, outbuf, length, 					bufsize,					ppsetup, setup_count,					ppparams, parameter_count,					ppdata, data_count);		} else {			return ERROR_DOS(ERRDOS,ERRnoaccess);		}	}	/*	 * Ensure minimum number of parameters sent.	 */	if(parameter_count < 54) {		DEBUG(0,("call_nt_transact_create - insufficient parameters (%u)\n", (unsigned int)parameter_count));		return ERROR_NT(NT_STATUS_INVALID_PARAMETER);	}	flags = IVAL(params,0);	access_mask = IVAL(params,8);	file_attributes = IVAL(params,20);	share_access = IVAL(params,24);	create_disposition = IVAL(params,28);	create_options = IVAL(params,32);	sd_len = IVAL(params,36);	ea_len = IVAL(params,40);	root_dir_fid = (uint16)IVAL(params,4);	/* Ensure the data_len is correct for the sd and ea values given. */	if ((ea_len + sd_len > data_count) ||			(ea_len > data_count) || (sd_len > data_count) ||			(ea_len + sd_len < ea_len) || (ea_len + sd_len < sd_len)) {		DEBUG(10,("call_nt_transact_create - ea_len = %u, sd_len = %u, data_count = %u\n",			(unsigned int)ea_len, (unsigned int)sd_len, (unsigned int)data_count ));		return ERROR_NT(NT_STATUS_INVALID_PARAMETER);	}	if (ea_len) {		if (!lp_ea_support(SNUM(conn))) {			DEBUG(10,("call_nt_transact_create - ea_len = %u but EA's not supported.\n",				(unsigned int)ea_len ));			return ERROR_NT(NT_STATUS_EAS_NOT_SUPPORTED);		}		if (ea_len < 10) {			DEBUG(10,("call_nt_transact_create - ea_len = %u - too small (should be more than 10)\n",				(unsigned int)ea_len ));			return ERROR_NT(NT_STATUS_INVALID_PARAMETER);		}	}	if (create_options & FILE_OPEN_BY_FILE_ID) {		return ERROR_NT(NT_STATUS_NOT_SUPPORTED);	}	/*	 * Get the file name.	 */	if(root_dir_fid != 0) {		/*		 * This filename is relative to a directory fid.		 */		files_struct *dir_fsp = file_fsp(params,4);		size_t dir_name_len;		if(!dir_fsp) {			return ERROR_DOS(ERRDOS,ERRbadfid);		}		if(!dir_fsp->is_directory) {			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);			}			/*			 * Check to see if this is a mac fork of some kind.			 */			if( is_ntfs_stream_name(fname)) {				return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);			}			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++;		}		{			pstring tmpname;			srvstr_get_path(inbuf, tmpname, params+53, sizeof(tmpname), parameter_count-53, STR_TERMINATE, &status);			if (!NT_STATUS_IS_OK(status)) {				return ERROR_NT(status);			}			pstrcat(fname, tmpname);		}	} else {		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);		}		/*		 * Check to see if this is a mac fork of some kind.		 */		if( is_ntfs_stream_name(fname)) {			return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);		}	}	oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;	oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;	/*	 * Check if POSIX semantics are wanted.	 */	set_posix_case_semantics(conn, file_attributes);    	RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);	unix_convert(fname,conn,0,&bad_path,&sbuf);	if (bad_path) {		restore_case_semantics(conn, file_attributes);		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);		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);			return ERROR_NT(status);		}	}	if (ea_len) {		ctx = talloc_init("NTTRANS_CREATE_EA");		if (!ctx) {			talloc_destroy(ctx);			restore_case_semantics(conn, file_attributes);			return ERROR_NT(NT_STATUS_NO_MEMORY);		}		pdata = data + sd_len;		/* We have already checked that ea_len <= data_count here. */		ea_list = read_nttrans_ea_list(ctx, pdata, ea_len);		if (!ea_list ) {			talloc_destroy(ctx);			restore_case_semantics(conn, file_attributes);			return ERROR_NT(NT_STATUS_INVALID_PARAMETER);		}	}	/*	 * If it's a request for a directory open, deal with it separately.	 */	if(create_options & FILE_DIRECTORY_FILE) {		/* Can't open a temp directory. IFS kit test. */		if (file_attributes & FILE_ATTRIBUTE_TEMPORARY) {			talloc_destroy(ctx);			restore_case_semantics(conn, file_attributes);			return ERROR_NT(NT_STATUS_INVALID_PARAMETER);		}		oplock_request = 0;		/*		 * We will get a create directory here if the Win32		 * app specified a security descriptor in the 		 * CreateDirectory() call.		 */		fsp = open_directory(conn, fname, &sbuf,					access_mask,					share_access,					create_disposition,					create_options,					&info);		if(!fsp) {			talloc_destroy(ctx);			restore_case_semantics(conn, file_attributes);			return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);		}	} else {		/*		 * Ordinary file case.		 */		fsp = open_file_ntcreate(conn,fname,&sbuf,					access_mask,					share_access,					create_disposition,					create_options,					file_attributes,					oplock_request,					&info);		if (!fsp) { 			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);					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) {					talloc_destroy(ctx);					restore_case_semantics(conn, file_attributes);					return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);				}			} else {				talloc_destroy(ctx);				restore_case_semantics(conn, file_attributes);				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);			}		} 	}	/*	 * According to the MS documentation, the only time the security	 * descriptor is applied to the opened file is iff we *created* the	 * file; an existing file stays the same.	 * 	 * Also, it seems (from observation) that you can open the file with	 * any access mask but you can still write the sd. We need to override	 * the granted access before we call set_sd	 * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.	 */	if (lp_nt_acl_support(SNUM(conn)) && sd_len && info == FILE_WAS_CREATED) {		uint32 saved_access_mask = fsp->access_mask;		/* We have already checked that sd_len <= data_count here. */		fsp->access_mask = FILE_GENERIC_ALL;		status = set_sd( fsp, data, sd_len, ALL_SECURITY_INFORMATION);		if (!NT_STATUS_IS_OK(status)) {			talloc_destroy(ctx);			close_file(fsp,False);

⌨️ 快捷键说明

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