From 6cf37e3d8da2670022e17c5dd4c0e42ac76dc841 Mon Sep 17 00:00:00 2001 From: Misaka_Company Date: Wed, 29 Jul 2026 16:43:19 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20169=20=E5=85=B1=E4=BA=AB?= =?UTF-8?q?=E8=AE=BF=E9=97=AE=EF=BC=9A=E8=AE=BF=E9=97=AE=E6=BA=90=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E5=89=8D=E6=98=BE=E5=BC=8F=E4=BB=A5=20169\Administrat?= =?UTF-8?q?or=20=E5=BB=BA=20SMB=20=E8=BF=9E=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 行。 --- src/runner.py | 4 ++++ src/source_watcher.py | 53 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/runner.py b/src/runner.py index 65077be..a38179b 100644 --- a/src/runner.py +++ b/src/runner.py @@ -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) diff --git a/src/source_watcher.py b/src/source_watcher.py index 75a9501..9133c7a 100644 --- a/src/source_watcher.py +++ b/src/source_watcher.py @@ -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\\\\ + (+密码) 建连。 + + 实现要点(与验证脚本一致): + - 先 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)