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

📄 nttrans.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	fsp = file_fsp(params, 0);	replace_if_exists = (SVAL(params,2) & RENAME_REPLACE_IF_EXISTS) ? True : False;	CHECK_FSP(fsp, conn);	srvstr_get_path_wcard(inbuf, new_name, params+4, sizeof(new_name), -1, STR_TERMINATE, &status, &path_contains_wcard);	if (!NT_STATUS_IS_OK(status)) {		return ERROR_NT(status);	}	status = rename_internals(conn, fsp->fsp_name,				  new_name, 0, replace_if_exists, path_contains_wcard);	if (!NT_STATUS_IS_OK(status))		return ERROR_NT(status);	/*	 * Rename was successful.	 */	send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);		DEBUG(3,("nt transact rename from = %s, to = %s succeeded.\n", 		 fsp->fsp_name, new_name));		/*	 * Win2k needs a changenotify request response before it will	 * update after a rename..	 */		process_pending_change_notify_queue((time_t)0);	return -1;}/****************************************************************************** Fake up a completely empty SD.*******************************************************************************/static size_t get_null_nt_acl(TALLOC_CTX *mem_ctx, SEC_DESC **ppsd){	size_t sd_size;	*ppsd = make_standard_sec_desc( mem_ctx, &global_sid_World, &global_sid_World, NULL, &sd_size);	if(!*ppsd) {		DEBUG(0,("get_null_nt_acl: Unable to malloc space for security descriptor.\n"));		sd_size = 0;	}	return sd_size;}/**************************************************************************** Reply to query a security descriptor.****************************************************************************/static int call_nt_transact_query_security_desc(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;	char *data = *ppdata;	prs_struct pd;	SEC_DESC *psd = NULL;	size_t sd_size;	uint32 security_info_wanted;	TALLOC_CTX *mem_ctx;	files_struct *fsp = NULL;        if(parameter_count < 8) {		return ERROR_DOS(ERRDOS,ERRbadfunc);	}	fsp = file_fsp(params,0);	if(!fsp) {		return ERROR_DOS(ERRDOS,ERRbadfid);	}	security_info_wanted = IVAL(params,4);	DEBUG(3,("call_nt_transact_query_security_desc: file = %s, info_wanted = 0x%x\n", fsp->fsp_name,			(unsigned int)security_info_wanted ));	params = nttrans_realloc(ppparams, 4);	if(params == NULL) {		return ERROR_DOS(ERRDOS,ERRnomem);	}	if ((mem_ctx = talloc_init("call_nt_transact_query_security_desc")) == NULL) {		DEBUG(0,("call_nt_transact_query_security_desc: talloc_init failed.\n"));		return ERROR_DOS(ERRDOS,ERRnomem);	}	/*	 * Get the permissions to return.	 */	if (!lp_nt_acl_support(SNUM(conn))) {		sd_size = get_null_nt_acl(mem_ctx, &psd);	} else {		sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fh->fd, security_info_wanted, &psd);	}	if (sd_size == 0) {		talloc_destroy(mem_ctx);		return(UNIXERROR(ERRDOS,ERRnoaccess));	}	DEBUG(3,("call_nt_transact_query_security_desc: sd_size = %lu.\n",(unsigned long)sd_size));	SIVAL(params,0,(uint32)sd_size);	if(max_data_count < sd_size) {		send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_BUFFER_TOO_SMALL,			params, 4, *ppdata, 0);		talloc_destroy(mem_ctx);		return -1;	}	/*	 * Allocate the data we will point this at.	 */	data = nttrans_realloc(ppdata, sd_size);	if(data == NULL) {		talloc_destroy(mem_ctx);		return ERROR_DOS(ERRDOS,ERRnomem);	}	/*	 * Init the parse struct we will marshall into.	 */	prs_init(&pd, 0, mem_ctx, MARSHALL);	/*	 * Setup the prs_struct to point at the memory we just	 * allocated.	 */	prs_give_memory( &pd, data, (uint32)sd_size, False);	/*	 * Finally, linearize into the outgoing buffer.	 */	if(!sec_io_desc( "sd data", &psd, &pd, 1)) {		DEBUG(0,("call_nt_transact_query_security_desc: Error in marshalling \security descriptor.\n"));		/*		 * Return access denied for want of a better error message..		 */ 		talloc_destroy(mem_ctx);		return(UNIXERROR(ERRDOS,ERRnoaccess));	}	/*	 * Now we can delete the security descriptor.	 */	talloc_destroy(mem_ctx);	send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, params, 4, data, (int)sd_size);	return -1;}/**************************************************************************** Reply to set a security descriptor. Map to UNIX perms or POSIX ACLs.****************************************************************************/static int call_nt_transact_set_security_desc(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;	char *data = *ppdata;	files_struct *fsp = NULL;	uint32 security_info_sent = 0;	NTSTATUS nt_status;	if(parameter_count < 8) {		return ERROR_DOS(ERRDOS,ERRbadfunc);	}	if((fsp = file_fsp(params,0)) == NULL) {		return ERROR_DOS(ERRDOS,ERRbadfid);	}	if(!lp_nt_acl_support(SNUM(conn))) {		goto done;	}	security_info_sent = IVAL(params,4);	DEBUG(3,("call_nt_transact_set_security_desc: file = %s, sent 0x%x\n", fsp->fsp_name,		(unsigned int)security_info_sent ));	if (data_count == 0) {		return ERROR_DOS(ERRDOS, ERRnoaccess);	}	if (!NT_STATUS_IS_OK(nt_status = set_sd( fsp, data, data_count, security_info_sent))) {		return ERROR_NT(nt_status);	}  done:	send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);	return -1;}   /**************************************************************************** Reply to NT IOCTL****************************************************************************/static int call_nt_transact_ioctl(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){	uint32 function;	uint16 fidnum;	files_struct *fsp;	uint8 isFSctl;	uint8 compfilter;	static BOOL logged_message;	char *pdata = *ppdata;	if (setup_count != 8) {		DEBUG(3,("call_nt_transact_ioctl: invalid setup count %d\n", setup_count));		return ERROR_NT(NT_STATUS_NOT_SUPPORTED);	}	function = IVAL(*ppsetup, 0);	fidnum = SVAL(*ppsetup, 4);	isFSctl = CVAL(*ppsetup, 6);	compfilter = CVAL(*ppsetup, 7);	DEBUG(10,("call_nt_transact_ioctl: function[0x%08X] FID[0x%04X] isFSctl[0x%02X] compfilter[0x%02X]\n", 		 function, fidnum, isFSctl, compfilter));	fsp=file_fsp(*ppsetup, 4);	/* this check is done in each implemented function case for now	   because I don't want to break anything... --metze	FSP_BELONGS_CONN(fsp,conn);*/	switch (function) {	case FSCTL_SET_SPARSE:		/* pretend this succeeded - tho strictly we should		   mark the file sparse (if the local fs supports it)		   so we can know if we need to pre-allocate or not */		DEBUG(10,("FSCTL_SET_SPARSE: called on FID[0x%04X](but not implemented)\n", fidnum));		send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);		return -1;		case FSCTL_0x000900C0:		/* pretend this succeeded - don't know what this really is		   but works ok like this --metze		 */		DEBUG(10,("FSCTL_0x000900C0: called on FID[0x%04X](but not implemented)\n",fidnum));		send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);		return -1;	case FSCTL_GET_REPARSE_POINT:		/* pretend this fail - my winXP does it like this		 * --metze		 */		DEBUG(10,("FSCTL_GET_REPARSE_POINT: called on FID[0x%04X](but not implemented)\n",fidnum));		send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_NOT_A_REPARSE_POINT, NULL, 0, NULL, 0);		return -1;	case FSCTL_SET_REPARSE_POINT:		/* pretend this fail - I'm assuming this because of the FSCTL_GET_REPARSE_POINT case.		 * --metze		 */		DEBUG(10,("FSCTL_SET_REPARSE_POINT: called on FID[0x%04X](but not implemented)\n",fidnum));		send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_NOT_A_REPARSE_POINT, NULL, 0, NULL, 0);		return -1;				case FSCTL_GET_SHADOW_COPY_DATA: /* don't know if this name is right...*/	{		/*		 * This is called to retrieve the number of Shadow Copies (a.k.a. snapshots)		 * and return their volume names.  If max_data_count is 16, then it is just		 * asking for the number of volumes and length of the combined names.		 *		 * pdata is the data allocated by our caller, but that uses		 * total_data_count (which is 0 in our case) rather than max_data_count.		 * Allocate the correct amount and return the pointer to let		 * it be deallocated when we return.		 */		SHADOW_COPY_DATA *shadow_data = NULL;		TALLOC_CTX *shadow_mem_ctx = NULL;		BOOL labels = False;		uint32 labels_data_count = 0;		uint32 i;		char *cur_pdata;		FSP_BELONGS_CONN(fsp,conn);		if (max_data_count < 16) {			DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) < 16 is invalid!\n",				max_data_count));			return ERROR_NT(NT_STATUS_INVALID_PARAMETER);		}		if (max_data_count > 16) {			labels = True;		}		shadow_mem_ctx = talloc_init("SHADOW_COPY_DATA");		if (shadow_mem_ctx == NULL) {			DEBUG(0,("talloc_init(SHADOW_COPY_DATA) failed!\n"));			return ERROR_NT(NT_STATUS_NO_MEMORY);		}		shadow_data = TALLOC_ZERO_P(shadow_mem_ctx,SHADOW_COPY_DATA);		if (shadow_data == NULL) {			DEBUG(0,("talloc_zero() failed!\n"));			talloc_destroy(shadow_mem_ctx);			return ERROR_NT(NT_STATUS_NO_MEMORY);		}				shadow_data->mem_ctx = shadow_mem_ctx;				/*		 * Call the VFS routine to actually do the work.		 */		if (SMB_VFS_GET_SHADOW_COPY_DATA(fsp, shadow_data, labels)!=0) {			talloc_destroy(shadow_data->mem_ctx);			if (errno == ENOSYS) {				DEBUG(5,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, not supported.\n", 					conn->connectpath));				return ERROR_NT(NT_STATUS_NOT_SUPPORTED);			} else {				DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, failed.\n", 					conn->connectpath));				return ERROR_NT(NT_STATUS_UNSUCCESSFUL);						}		}		labels_data_count = (shadow_data->num_volumes*2*sizeof(SHADOW_COPY_LABEL))+2;		if (!labels) {			data_count = 16;		} else {			data_count = 12+labels_data_count+4;		}		if (max_data_count<data_count) {			DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) too small (%u) bytes needed!\n",				max_data_count,data_count));			talloc_destroy(shadow_data->mem_ctx);			return ERROR_NT(NT_STATUS_BUFFER_TOO_SMALL);		}		pdata = nttrans_realloc(ppdata, data_count);		if (pdata == NULL) {			talloc_destroy(shadow_data->mem_ctx);			return ERROR_NT(NT_STATUS_NO_MEMORY);		}				cur_pdata = pdata;		/* num_volumes 4 bytes */		SIVAL(pdata,0,shadow_data->num_volumes);		if (labels) {			/* num_labels 4 bytes */			SIVAL(pdata,4,shadow_data->num_volumes);		}		/* needed_data_count 4 bytes */		SIVAL(pdata,8,labels_data_count);		cur_pdata+=12;		DEBUG(10,("FSCTL_GET_SHADOW_COPY_DATA: %u volumes for path[%s].\n",			shadow_data->num_volumes,fsp->fsp_name));		if (labels && shadow_data->labels) {			for (i=0;i<shadow_data->num_volumes;i++) {				srvstr_push(outbuf, cur_pdata, shadow_data->labels[i], 2*sizeof(SHADOW_COPY_LABEL), STR_UNICODE|STR_TERMINATE);				cur_pdata+=2*sizeof(SHADOW_COPY_LABEL);				DEBUGADD(10,("Label[%u]: '%s'\n",i,shadow_data->labels[i]));			}		}		talloc_destroy(shadow_data->mem_ctx);		send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, pdata, data_count);		return -1;        }        	case FSCTL_FIND_FILES_BY_SID: /* I hope this name is right */	{		/* pretend this succeeded - 		 * 		 * we have to send back a list with all files owned by this SID		 *		 * but I have to check that --metze		 */		DOM_SID sid;		uid_t uid;		size_t sid_len = MIN(data_count-4,SID_MAX_SIZE);				DEBUG(10,("FSCTL_FIND_FILES_BY_SID: called on FID[0x%04X]\n",fidnum));		FSP_BELONGS_CONN(fsp,conn);		/* unknown 4 bytes: this is not the length of the sid :-(  */		/*unknown = IVAL(pdata,0);*/				sid_parse(pdata+4,sid_len,&sid);		DEBUGADD(10,("for SID: %s\n",sid_string_static(&sid)));		if (!NT_STATUS_IS_OK(sid_to_uid(&sid, &uid))) {			DEBUG(0,("sid_to_uid: failed, sid[%s] sid_len[%lu]\n",				sid_string_static(&sid),(unsigned long)sid_len));			uid = (-1);		}				/* we can take a look at the find source :-)		 *		 * find ./ -uid $uid  -name '*'   is what we need here		 *		 *		 * and send 4bytes len and then NULL terminated unicode strings		 * for each file		 *		 * but I don't know how to deal with the paged results		 * (maybe we can hang the result anywhere in the fsp struct)		 *		 * we don't send all files at once		 * and at the next we should *not* start from the beginning, 		 * so we have to cache the result 		 *		 * --metze		 */				/* this works for now... */		send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);		return -1;		}		default:		if (!logged_message) {			logged_message = True; /* Only print this once... */			DEBUG(0,("call_nt_transact_ioctl(0x%x): Currently not implemented.\n",				 function));		}	}	return ERROR_NT(NT_STATUS_NOT_SUPPORTED);}#ifdef HAVE_SYS_QUOTAS/**************************************************************************** Reply to get user quota ****************************************************************************/static int call_nt_transact_get_user_quota(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){	NTSTATUS nt_status = NT_STATUS_OK;	char *params = *ppparams;	char *pdata = *ppda

⌨️ 快捷键说明

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