修复 169 共享访问:访问源文件前显式以 169\Administrator 建 SMB 连接

169 只认识自身账户,不认识 114 本地账户(peng/svc_app/LocalSystem 计算机账户),
直接读 UNC 导致持续 WinError 5 拒绝访问、同步中断。
- 新增 source_watcher.ensure_share_connected:run_once 访问 UNC 前用 net use
  以配置凭据(169\Administrator, 空密码, 169 允许空密码网络登录)建连;
  先 delete 旧连接避免用户名冲突;建连失败仅告警,交给既有跳过逻辑。
- 凭据通过 config source_share 段配置(含空密码);config.yaml 仍被 gitignore。
- 本地 dry-run 验证:建连成功、源文件可下载(13647 行)、清洗后保留 13606 行。
This commit is contained in:
Misaka_Company
2026-07-29 16:43:19 +08:00
parent 75ed7c775e
commit 6cf37e3d8d
2 changed files with 57 additions and 0 deletions

View File

@@ -122,6 +122,10 @@ def run_once(cfg, source_path=None, dry_run=False):
local_file = source_path
logger.info("使用本地源: %s", local_file)
else:
# 访问 169 共享前,先确保已用配置的凭据建立 SMB 连接
# 169 不认识 114 本地账户,必须显式以 169\Administrator 建连,
# 否则读 UNC 会 WinError 5 拒绝访问)
source_watcher.ensure_share_connected(cfg)
if not source_watcher.has_changed(unc, meta_path):
return
local_file = source_watcher.download(unc, cache)

View File

@@ -3,6 +3,7 @@ import json
import logging
import os
import shutil
import subprocess
import time
from datetime import datetime
from pathlib import Path
@@ -51,6 +52,58 @@ def save_baseline(meta_path, meta):
json.dump(meta, f)
def ensure_share_connected(cfg):
"""访问 169 共享前,显式以配置的账户建立 SMB 连接。
169 只认识自身的账户(如 Administrator不认识 114 的本地账户
peng / svc_app / LocalSystem 的计算机账户),直接读 UNC 会
WinError 5 拒绝访问。故在访问源文件前用 ``net use`` 以 169\\\\<user>
(+密码) 建连。
实现要点(与验证脚本一致):
- 先 delete 可能已存在的旧连接,避免“多个不同的用户名/密码”冲突;
- 再以指定账户+密码建新连接169 的 LimitBlankPasswordUse=0
允许空密码网络登录)。
建连失败不抛异常:仅告警,交由 has_changed/download 既有的
“源不可达则跳过本轮”逻辑处理,不会让循环崩溃。
"""
share_cfg = cfg.get("source_share") or {}
if not share_cfg.get("enabled", False):
return
if os.name != "nt":
logger.debug("非 Windows 环境,跳过 net use 共享连接")
return
server = share_cfg.get("server")
username = share_cfg.get("username")
password = share_cfg.get("password", "")
if not server or not username:
logger.warning("source_share 配置不完整(缺 server/username),跳过建连")
return
# 1) 清理可能已存在的旧连接(忽略失败)
try:
subprocess.run(["net", "use", server, "/delete", "/y"],
capture_output=True, timeout=30)
except Exception as e: # noqa: BLE001
logger.debug("清理旧共享连接时异常(可忽略): %s", e)
# 2) 用指定账户 + 密码建立新连接
# 注net use 输出为中文 GBK 编码,按字节捕获后容错解码,避免 UTF-8
# 解码崩溃(不影响建连结果,仅用于失败时记录日志)。
cmd = ["net", "use", server, password, f"/user:{username}"]
try:
res = subprocess.run(cmd, capture_output=True, timeout=30)
except Exception as e: # noqa: BLE001
logger.warning("建立共享连接异常: %s", e)
return
if res.returncode != 0:
raw = res.stderr or res.stdout
msg = raw.decode("gbk", "replace").strip() if raw else ""
logger.warning("共享连接认证失败(源将不可达): %s", msg)
return
logger.info("已用 %s 身份建立到 %s 的共享连接", username, server)
def has_changed(path, meta_path):
try:
cur = get_source_meta(path)