Phase 2: Fix SSH_FXP_ATTRS uid/gid fields (resolve "? 0 0" issue)
Some checks failed
Test / test (push) Has been cancelled
Test / build (push) Has been cancelled

- Phase 2.2: Add MetadataExt import to get uid/gid from file metadata
- Phase 2.3: Add SSH_FILEXFER_ATTR_UIDGID flag to attrs.flags
- Phase 2.4: Get uid/gid from metadata.uid() and metadata.gid()
- Result: ls -la now shows correct uid (501) and gid (0) instead of "? 0 0"

Root cause: SSH_FILEXFER_ATTR_UIDGID flag was missing, so uid/gid not serialized
Fix: Add flag and get uid/gid using std::os::unix::fs::MetadataExt

Test verification:
- Before: -rw-r--r--    ? 0        0            1024
- After:  -rw-r--r--    ? 501      0            1024  

Reference: OpenSSH sftp-server.c: stat_to_attrib()
This commit is contained in:
Warren
2026-06-17 19:44:22 +08:00
parent 063c0a589f
commit 1b0105accf

View File

@@ -9,6 +9,7 @@ use std::path::{Path, PathBuf};
use std::fs::{self, File, OpenOptions};
use std::io::{Read, Write, Seek, SeekFrom};
use std::os::unix::fs::PermissionsExt; // 导入PermissionsExt traitUnix标准
use std::os::unix::fs::MetadataExt; // ⭐⭐⭐⭐⭐ Phase 2.2: 导入MetadataExt trait获取uid/gid
/// SFTP packet类型参考draft-ietf-secsh-filexfer-02.txt
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -154,13 +155,19 @@ impl SftpAttrs {
pub fn from_metadata(metadata: &fs::Metadata) -> Self {
let mut attrs = Self::new();
// ⭐⭐⭐⭐⭐ Phase 2.2: 添加 uid/gid 字段(修复 "? 0 0" 权限显示问题)
attrs.flags = SftpAttrFlags::SSH_FILEXFER_ATTR_SIZE
| SftpAttrFlags::SSH_FILEXFER_ATTR_UIDGID // ⭐⭐⭐⭐⭐ 添加 UIDGID flag
| SftpAttrFlags::SSH_FILEXFER_ATTR_PERMISSIONS
| SftpAttrFlags::SSH_FILEXFER_ATTR_ACMODTIME;
attrs.size = Some(metadata.len());
attrs.permissions = Some(metadata.permissions().mode());
// ⭐⭐⭐⭐⭐ Phase 2.2: 获取 uid/gid参考OpenSSH sftp-server.c: stat_to_attrib
attrs.uid = Some(metadata.uid());
attrs.gid = Some(metadata.gid());
if let Ok(atime) = metadata.accessed() {
attrs.atime = Some(atime.duration_since(std::time::UNIX_EPOCH).unwrap().as_secs() as u32);
}