问题现象

在 Windows 上使用 Codex 桌面版(从 Microsoft Store 安装)时,所有 shell 命令均无法执行,报错:

windows sandbox: CreateProcessWithLogonW failed: 1385

错误码 1385 = ERROR_LOGON_TYPE_NOT_GRANTED(“用户未被授予此计算机上所请求的登录类型”)。
文件编辑(apply_patch)正常,但 whoamidir 等任何需要执行命令的操作全部失败。

环境

  • Windows 10 (10.0.19041),PowerShell 5.1
  • Windows 加入企业域(以下简称 DOMAIN
  • Codex 桌面版从 Microsoft Store 安装
  • 域用户,本地管理员

排查过程

第一步:给账户加 SeBatchLogonRight

错误信息指向 CreateProcessWithLogonW,这个 API 要求被登录用户拥有“作为批处理作业登录”(SeBatchLogonRight)权限。

操作方式(二选一):

  • secpol.msc → 本地策略 → 用户权限分配 → “作为批处理作业登录” → 添加当前用户
  • 或用 secedit 命令行修改

修改后用 secedit /export 确认策略里确实包含了当前用户的 SID。

结果:注销重新登录后仍然报 1385。

第二步:排查 Deny 权限

Windows 用户权限分配中,Deny 优先于 Allow。检查策略里是否存在 SeDenyBatchLogonRight

$cfg = "$env:TEMP\check.cfg"
secedit /export /cfg $cfg /quiet
Select-String -Path $cfg -Pattern "SeDeny.*Logon"

发现存在 SeDenyBatchLogonRight,指向另一个域组的 SID。但用 whoami /groups 确认当前用户不在该组中。

进一步检查所有 SeDeny 条目:

SeDenyNetworkLogonRight         = *S-1-5-21-...-xxx  (某限制组)
SeDenyBatchLogonRight           = *S-1-5-21-...-xxx  (某限制组)
SeDenyInteractiveLogonRight     = *S-1-5-21-...-xxx
SeDenyRemoteInteractiveLogonRight = *S-1-5-21-...-xxx

当前用户不在这些组里,Deny 不应该生效。排除此方向。

第三步:确认 OS 层面 batch logon 是否可用

直接调用 Win32 LogonUser API,用 Batch 登录类型(type 4)测试:

$cred = Get-Credential "$env:USERDOMAIN\$env:USERNAME"
Add-Type @"
using System;
using System.Runtime.InteropServices;
public class Logon {
    [DllImport("advapi32.dll", SetLastError = true)]
    public static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken);
}
"@
$token = [IntPtr]::Zero
$pw = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($cred.Password)
$pwPlain = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($pw)
$user = $cred.UserName.Split('\')
$result = [Logon]::LogonUser($user[1], $user[0], $pwPlain, 4, 0, [ref]$token)
$err = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
if ($result) { Write-Host "Batch logon SUCCESS" } else { Write-Host "FAILED - error $err" }

结果:Batch logon SUCCESS

进一步测试所有 5 种登录类型,全部成功:

Interactive (type 2):        SUCCESS
Network (type 3):            SUCCESS
Batch (type 4):              SUCCESS
NetworkCleartext (type 8):   SUCCESS
NewCredentials (type 9):     SUCCESS

结论:OS 层面权限完全正常,问题不在用户权限分配

第四步:确认 seclogon 服务

CreateProcessWithLogonW 依赖 Secondary Logon 服务(seclogon):

Get-Service seclogon

结果:服务状态 Running,启动类型 Manual。排除此方向。

第五步:从 Codex 二进制提取 sandbox 模式

既然 OS 层面一切正常,问题出在 Codex 的沙箱实现。从 Codex 的 codex.exe 二进制中搜索 sandbox 相关字符串:

$exe = "C:\Program Files\WindowsApps\OpenAI.Codex_*\app\resources\codex.exe"
$text = [System.IO.File]::ReadAllText($exe, [System.Text.Encoding]::GetEncoding("iso-8859-1"))
# 搜索 sandbox 附近的字符串
$text.Substring($text.IndexOf("elevated") - 40, 120)

sandbox.rs 代码段附近发现两个模式值:elevatedunelevated

同时发现二进制同时导入了两个 Windows API:

CreateProcessWithLogonW   ← elevated 模式使用,报 1385
CreateProcessAsUserW      ← unelevated 模式可能使用

第六步:切换 sandbox 模式

修改 ~/.codex/config.toml

# 修改前(报 1385)
[windows]
sandbox = "elevated"
修改后(正常)
[windows]
sandbox = "unelevated"

完全退出 Codex,重新打开,whoami 成功返回用户名,所有 shell 命令恢复正常。

问题解决。

根因分析

层面 结论
用户权限(SeBatchLogonRight) 正常,OS 层面 LogonUser(batch) 测试通过
Deny 权限(SeDenyBatchLogonRight) 存在但当前用户不在 deny 组中
seclogon 服务 正常运行
所有 5 种登录类型 全部成功
Codex sandbox = "elevated" CreateProcessWithLogonW 创建沙箱进程,在域环境 + Store 应用 token 上下文下报 1385
Codex sandbox = "unelevated" 用不同方式创建进程(CreateProcessAsUserWCreateProcess),绕过 1385

CreateProcessWithLogonWLogonUser 的关键区别:

  • LogonUser 只需要被登录用户的权限(SeBatchLogonRight),调用方不需要特殊权限
  • CreateProcessWithLogonW 通过 seclogon 服务创建进程,调用方进程的 token 上下文会影响调用结果
  • Codex 作为 Store 应用,即使以管理员身份运行,其进程 token 可能经过过滤,导致 CreateProcessWithLogonW 失败

最终解决方案

编辑 C:\Users\<你的用户名>\.codex\config.toml,将:

[windows]
sandbox = "elevated"

改为:

[windows]
sandbox = "unelevated"

保存后完全退出 Codex(任务管理器确认无残留进程),重新打开即可。

补充说明

如果你的 config.toml 里没有 [windows] 段

手动添加即可:

[windows]
sandbox = "unelevated"

elevated 和 unelevated 的区别

  • elevated:通过 CreateProcessWithLogonW 创建提升权限的沙箱进程,隔离性更强,但对调用方 token 要求更高
  • unelevated:通过其他方式创建进程,不依赖 CreateProcessWithLogonW,兼容性更好

适用场景

这个问题主要出现在以下条件同时满足时:

  1. Windows 加入企业域
  2. Codex 从 Microsoft Store 安装
  3. 域策略对用户 token 有一定限制

如果你遇到同样的 1385 错误,直接尝试切换到 unelevated 模式,大概率能解决。
如果不行,再按本文的排查步骤逐步确认 OS 层面权限是否正常。

排查命令速查

# 1. 检查 SeBatchLogonRight
$cfg = "$env:TEMP\check.cfg"
secedit /export /cfg $cfg /quiet
Select-String -Path $cfg -Pattern "SeBatchLogonRight"
2. 检查 SeDeny 权限
Select-String -Path $cfg -Pattern "SeDeny.*Logon"
3. 确认当前用户 SID
whoami /user
4. 确认所属组
whoami /groups
5. 检查 seclogon 服务
Get-Service seclogon
6. 直接测试 LogonUser (Batch)
见上方第三步的 PowerShell 脚本
7. 从 Codex 二进制搜索 sandbox 模式
$exe = "C:\Program Files\WindowsApps\OpenAI.Codex_*\app\resources\codex.exe"
$text = [System.IO.File]::ReadAllText($exe, [System.Text.Encoding]::GetEncoding("iso-8859-1"))
$text.Substring($text.IndexOf("elevated") - 40, 120)
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐