From 1b0105accf716e829c3d8814b3b68f7eb815ff22 Mon Sep 17 00:00:00 2001 From: Warren Date: Wed, 17 Jun 2026 19:44:22 +0800 Subject: [PATCH] Phase 2: Fix SSH_FXP_ATTRS uid/gid fields (resolve "? 0 0" issue) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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() --- markbase-core/src/ssh_server/sftp_handler.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/markbase-core/src/ssh_server/sftp_handler.rs b/markbase-core/src/ssh_server/sftp_handler.rs index 7c9b4ff..1a9a023 100644 --- a/markbase-core/src/ssh_server/sftp_handler.rs +++ b/markbase-core/src/ssh_server/sftp_handler.rs @@ -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 trait(Unix标准) +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); }