修复 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:
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user