trans2.c

来自「samba-3.0.22.tar.gz 编译smb服务器的源码」· C语言 代码 · 共 2,183 行 · 第 1/5 页

C
2,183
字号
		return ERROR_NT(NT_STATUS_NO_MEMORY);	}	*pparams = params;	SSVAL(params,0,fsp->fnum);	SSVAL(params,2,open_attr);	srv_put_dos_date2(params,4, mtime);	SIVAL(params,8, (uint32)size);	SSVAL(params,12,deny_mode);	SSVAL(params,14,0); /* open_type - file or directory. */	SSVAL(params,16,0); /* open_state - only valid for IPC device. */	if (oplock_request && lp_fake_oplocks(SNUM(conn))) {		smb_action |= EXTENDED_OPLOCK_GRANTED;	}	SSVAL(params,18,smb_action);	/*	 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.	 */	SIVAL(params,20,inode);	SSVAL(params,24,0); /* Padding. */	if (flags & 8) {		uint32 ea_size = estimate_ea_size(conn, fsp, fname);		SIVAL(params, 26, ea_size);	} else {		SIVAL(params, 26, 0);	}	/* Send the required number of replies */	send_trans2_replies(outbuf, bufsize, params, 30, *ppdata, 0);	return -1;}/********************************************************* Routine to check if a given string matches exactly. as a special case a mask of "." does NOT match. That is required for correct wildcard semantics Case can be significant or not.**********************************************************/static BOOL exact_match(char *str,char *mask, BOOL case_sig) {	if (mask[0] == '.' && mask[1] == 0)		return False;	if (case_sig)			return strcmp(str,mask)==0;	if (StrCaseCmp(str,mask) != 0) {		return False;	}	if (ms_has_wild(str)) {		return False;	}	return True;}/**************************************************************************** Return the filetype for UNIX extensions.****************************************************************************/static uint32 unix_filetype(mode_t mode){	if(S_ISREG(mode))		return UNIX_TYPE_FILE;	else if(S_ISDIR(mode))		return UNIX_TYPE_DIR;#ifdef S_ISLNK	else if(S_ISLNK(mode))		return UNIX_TYPE_SYMLINK;#endif#ifdef S_ISCHR	else if(S_ISCHR(mode))		return UNIX_TYPE_CHARDEV;#endif#ifdef S_ISBLK	else if(S_ISBLK(mode))		return UNIX_TYPE_BLKDEV;#endif#ifdef S_ISFIFO	else if(S_ISFIFO(mode))		return UNIX_TYPE_FIFO;#endif#ifdef S_ISSOCK	else if(S_ISSOCK(mode))		return UNIX_TYPE_SOCKET;#endif	DEBUG(0,("unix_filetype: unknown filetype %u", (unsigned)mode));	return UNIX_TYPE_UNKNOWN;}/**************************************************************************** Map wire perms onto standard UNIX permissions. Obey share restrictions.****************************************************************************/static mode_t unix_perms_from_wire( connection_struct *conn, SMB_STRUCT_STAT *pst, uint32 perms){	mode_t ret = 0;	if (perms == SMB_MODE_NO_CHANGE)		return pst->st_mode;	ret |= ((perms & UNIX_X_OTH ) ? S_IXOTH : 0);	ret |= ((perms & UNIX_W_OTH ) ? S_IWOTH : 0);	ret |= ((perms & UNIX_R_OTH ) ? S_IROTH : 0);	ret |= ((perms & UNIX_X_GRP ) ? S_IXGRP : 0);	ret |= ((perms & UNIX_W_GRP ) ? S_IWGRP : 0);	ret |= ((perms & UNIX_R_GRP ) ? S_IRGRP : 0);	ret |= ((perms & UNIX_X_USR ) ? S_IXUSR : 0);	ret |= ((perms & UNIX_W_USR ) ? S_IWUSR : 0);	ret |= ((perms & UNIX_R_USR ) ? S_IRUSR : 0);#ifdef S_ISVTX	ret |= ((perms & UNIX_STICKY ) ? S_ISVTX : 0);#endif#ifdef S_ISGID	ret |= ((perms & UNIX_SET_GID ) ? S_ISGID : 0);#endif#ifdef S_ISUID	ret |= ((perms & UNIX_SET_UID ) ? S_ISUID : 0);#endif	if (VALID_STAT(*pst) && S_ISDIR(pst->st_mode)) {		ret &= lp_dir_mask(SNUM(conn));		/* Add in force bits */		ret |= lp_force_dir_mode(SNUM(conn));	} else {		/* Apply mode mask */		ret &= lp_create_mask(SNUM(conn));		/* Add in force bits */		ret |= lp_force_create_mode(SNUM(conn));	}	return ret;}/**************************************************************************** Get a level dependent lanman2 dir entry.****************************************************************************/static BOOL get_lanman2_dir_entry(connection_struct *conn,				  void *inbuf, void *outbuf,				 char *path_mask,uint32 dirtype,int info_level,				 int requires_resume_key,				 BOOL dont_descend,char **ppdata, 				 char *base_data, int space_remaining, 				 BOOL *out_of_space, BOOL *got_exact_match,				 int *last_entry_off, struct ea_list *name_list, TALLOC_CTX *ea_ctx){	const char *dname;	BOOL found = False;	SMB_STRUCT_STAT sbuf;	pstring mask;	pstring pathreal;	pstring fname;	char *p, *q, *pdata = *ppdata;	uint32 reskey=0;	long prev_dirpos=0;	uint32 mode=0;	SMB_OFF_T file_size = 0;	SMB_BIG_UINT allocation_size = 0;	uint32 len;	time_t mdate=0, adate=0, cdate=0;	char *nameptr;	char *last_entry_ptr;	BOOL was_8_3;	uint32 nt_extmode; /* Used for NT connections instead of mode */	BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');	BOOL check_mangled_names = lp_manglednames(SNUM(conn));	*fname = 0;	*out_of_space = False;	*got_exact_match = False;	if (!conn->dirptr)		return(False);	p = strrchr_m(path_mask,'/');	if(p != NULL) {		if(p[1] == '\0')			pstrcpy(mask,"*.*");		else			pstrcpy(mask, p+1);	} else		pstrcpy(mask, path_mask);	while (!found) {		BOOL got_match;		/* Needed if we run out of space */		long curr_dirpos = prev_dirpos = dptr_TellDir(conn->dirptr);		dname = dptr_ReadDirName(conn->dirptr,&curr_dirpos,&sbuf);		/*		 * Due to bugs in NT client redirectors we are not using		 * resume keys any more - set them to zero.		 * Check out the related comments in findfirst/findnext.		 * JRA.		 */		reskey = 0;		DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %ld\n",			(long)conn->dirptr,curr_dirpos));      		if (!dname) 			return(False);		pstrcpy(fname,dname);      		if(!(got_match = *got_exact_match = exact_match(fname, mask, conn->case_sensitive)))			got_match = mask_match(fname, mask, conn->case_sensitive);		if(!got_match && check_mangled_names && !mangle_is_8_3(fname, False, SNUM(conn))) {			/*			 * It turns out that NT matches wildcards against			 * both long *and* short names. This may explain some			 * of the wildcard wierdness from old DOS clients			 * that some people have been seeing.... JRA.			 */			pstring newname;			pstrcpy( newname, fname);			mangle_map( newname, True, False, SNUM(conn));			if(!(got_match = *got_exact_match = exact_match(newname, mask, conn->case_sensitive)))				got_match = mask_match(newname, mask, conn->case_sensitive);		}		if(got_match) {			BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));			if (dont_descend && !isdots)				continue;	  			pstrcpy(pathreal,conn->dirpath);			if(needslash)				pstrcat(pathreal,"/");			pstrcat(pathreal,dname);			if (INFO_LEVEL_IS_UNIX(info_level)) {				if (SMB_VFS_LSTAT(conn,pathreal,&sbuf) != 0) {					DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",						pathreal,strerror(errno)));					continue;				}			} else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,pathreal,&sbuf) != 0) {				/* Needed to show the msdfs symlinks as 				 * directories */				if(lp_host_msdfs() && 				   lp_msdfs_root(SNUM(conn)) &&				   is_msdfs_link(NULL,conn, pathreal, NULL, NULL,						 &sbuf)) {					DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal));					sbuf.st_mode = (sbuf.st_mode & 0xFFF) | S_IFDIR;				} else {					DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",						pathreal,strerror(errno)));					continue;				}			}			mode = dos_mode(conn,pathreal,&sbuf);			if (!dir_check_ftype(conn,mode,dirtype)) {				DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));				continue;			}			file_size = get_file_size(sbuf);			allocation_size = get_allocation_size(conn,NULL,&sbuf);			mdate = sbuf.st_mtime;			adate = sbuf.st_atime;			cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));			if (lp_dos_filetime_resolution(SNUM(conn))) {				cdate &= ~1;				mdate &= ~1;				adate &= ~1;			}			if(mode & aDIR) {				/* This is necessary, as otherwise the				 * desktop.ini file in this folder is				 * ignored */				mode |= (lp_profile_acls(SNUM(conn)) ? aRONLY : 0);				file_size = 0;			}			DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));	  			found = True;		}	}	mangle_map(fname,False,True,SNUM(conn));	p = pdata;	last_entry_ptr = p;	nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;	switch (info_level) {		case SMB_FIND_INFO_STANDARD:			DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_INFO_STANDARD\n"));			if(requires_resume_key) {				SIVAL(p,0,reskey);				p += 4;			}			srv_put_dos_date2(p,0,cdate);			srv_put_dos_date2(p,4,adate);			srv_put_dos_date2(p,8,mdate);			SIVAL(p,12,(uint32)file_size);			SIVAL(p,16,(uint32)allocation_size);			SSVAL(p,20,mode);			p += 23;			nameptr = p;			p += align_string(outbuf, p, 0);			len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);			if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {				if (len > 2) {					SCVAL(nameptr, -1, len - 2);				} else {					SCVAL(nameptr, -1, 0);				}			} else {				if (len > 1) {					SCVAL(nameptr, -1, len - 1);				} else {					SCVAL(nameptr, -1, 0);				}			}			p += len;			break;		case SMB_FIND_EA_SIZE:			DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_SIZE\n"));			if(requires_resume_key) {				SIVAL(p,0,reskey);				p += 4;			}			srv_put_dos_date2(p,0,cdate);			srv_put_dos_date2(p,4,adate);			srv_put_dos_date2(p,8,mdate);			SIVAL(p,12,(uint32)file_size);			SIVAL(p,16,(uint32)allocation_size);			SSVAL(p,20,mode);			{				unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);				SIVAL(p,22,ea_size); /* Extended attributes */			}			p += 27;			nameptr = p - 1;			len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE | STR_NOALIGN);			if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {				if (len > 2) {					len -= 2;				} else {					len = 0;				}			} else {				if (len > 1) {					len -= 1;				} else {					len = 0;				}			}			SCVAL(nameptr,0,len);			p += len;			SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */			break;		case SMB_FIND_EA_LIST:		{			struct ea_list *file_list = NULL;			size_t ea_len = 0;			DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_LIST\n"));			if (!name_list) {				return False;			}			if(requires_resume_key) {				SIVAL(p,0,reskey);				p += 4;			}			srv_put_dos_date2(p,0,cdate);			srv_put_dos_date2(p,4,adate);			srv_put_dos_date2(p,8,mdate);			SIVAL(p,12,(uint32)file_size);			SIVAL(p,16,(uint32)allocation_size);			SSVAL(p,20,mode);			p += 22; /* p now points to the EA area. */			file_list = get_ea_list_from_file(ea_ctx, conn, NULL, pathreal, &ea_len);			name_list = ea_list_union(name_list, file_list, &ea_len);			/* We need to determine if this entry will fit in the space available. */			/* Max string size is 255 bytes. */			if (PTR_DIFF(p + 255 + ea_len,pdata) > space_remaining) {				/* Move the dirptr back to prev_dirpos */				dptr_SeekDir(conn->dirptr, prev_dirpos);				*out_of_space = True;				DEBUG(9,("get_lanman2_dir_entry: out of space\n"));				return False; /* Not finished - just out of space */			}			/* Push the ea_data followed by the name. */			p += fill_ea_buffer(ea_ctx, p, space_remaining, conn, name_list);			nameptr = p;			len = srvstr_push(outbuf, p + 1, fname, -1, STR_TERMINATE | STR_NOALIGN);			if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {				if (len > 2) {					len -= 2;				} else {					len = 0;				}			} else {				if (len > 1) {					len -= 1;				} else {					len = 0;				}			}			SCVAL(nameptr,0,len);			p += len + 1;			SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */			break;		}		case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:			DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));			was_8_3 = mangle_is_8_3(fname, True, SNUM(conn));

⌨️ 快捷键说明

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