修复 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 local_file = source_path
logger.info("使用本地源: %s", local_file) logger.info("使用本地源: %s", local_file)
else: 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): if not source_watcher.has_changed(unc, meta_path):
return return
local_file = source_watcher.download(unc, cache) local_file = source_watcher.download(unc, cache)

View File

@@ -3,6 +3,7 @@ import json
import logging import logging
import os import os
import shutil import shutil
import subprocess
import time import time
from datetime import datetime from datetime import datetime
from pathlib import Path from pathlib import Path
@@ -51,6 +52,58 @@ def save_baseline(meta_path, meta):
json.dump(meta, f) 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): def has_changed(path, meta_path):
try: try:
cur = get_source_meta(path) cur = get_source_meta(path)