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 + -
显示快捷键?