IBM DB2 iSeries 错误 CWB_MP_TI_EVENT 访问被拒绝

问题描述 投票:0回答:1

我正在尝试使用 IBM 提供的 .NET 核心库的 alpha 版本连接到 AS400 上的 DB2 数据库,而我的项目是用 .NET 8 编写的。

由于我有多个服务器要连接,因此它们在某处配置,并且我使用代码动态创建连接字符串:

    iDB2ConnectionStringBuilder builder = new()
    {
        DataSource = "[ServerAddress]",
        UserID = "[User]",
        Password = "[Password]",
        PersistSecurityInfo = true
    };

然后我使用

builder.ConnectionString
打开连接。

当我在生产环境中发布此代码时,出现以下错误:

System.TypeInitializationException: The type initializer for 'Alfa.Data.DB2.iSeries.iDB2Trace' threw an exception.
 ---> System.UnauthorizedAccessException: Access to the path 'CWB_MP_TI_EVENT' is denied.
   at System.Threading.EventWaitHandle.CreateEventCore(Boolean initialState, EventResetMode mode, String name, Boolean& createdNew)
   at Alfa.Data.DB2.iSeries.iDB2NamedEvent..ctor(String eventName)
   at Alfa.Data.DB2.iSeries.iDB2Trace..cctor()
   --- End of inner exception stack trace ---
   at Alfa.Data.DB2.iSeries.iDB2Trace.get_Tracing()
   at Alfa.Data.DB2.iSeries.iDB2ConnectionStringBuilder..ctor()

异常是由

iDB2NamedEvent
的构造函数引发的,
iDB2Trace
又被
iDB2ConnectionStringBuilder
调用,所以显然我用来实际打开连接的代码都没有被调用。

我对dll进行了逆向工程,找到了抛出异常的方法的代码,即:

internal iDB2NamedEvent(string eventName)
{
    SecurityPermission securityPermission = new SecurityPermission(SecurityPermissionFlag.UnmanagedCode);
    waitHandle = null;
    string identity = (new SecurityIdentifier(WellKnownSidType.WorldSid, null).Translate(typeof(NTAccount)) as NTAccount).ToString();
    try
    {
        securityPermission.Assert();
        EventWaitHandleSecurity eventWaitHandleSecurity = new EventWaitHandleSecurity();
        EventWaitHandleAccessRule rule = new EventWaitHandleAccessRule(identity, EventWaitHandleRights.FullControl, AccessControlType.Allow);
        eventWaitHandleSecurity.AddAccessRule(rule);
        waitHandle = new EventWaitHandle(initialState: false, EventResetMode.ManualReset, "CWB_MP_TI_EVENT", out var _);
    }
    catch
    {
        CodeAccessPermission.RevertAssert();
        throw;
    }

    CodeAccessPermission.RevertAssert();
}

此代码在 Windows 服务和 IIS 中的某些 ASP.NET Web 服务中运行。现在为了使其工作,我必须在这两种情况下将他们运行的用户设置为

Local System
。如果我使用任何不同的用户,我会收到错误。

我已经谷歌搜索了两天,但没有找到任何可以帮助的东西,任何想法将不胜感激。

c# .net db2
1个回答
0
投票

错误的根本原因在于与创建或访问命名事件相关的权限限制。特别是,CWB_MP_TI_EVENT 受到强制提升权限的安全策略的约束。当应用程序在与本地系统不同的用户上下文下运行时,可能不存在必要的权限,从而触发 UnauthorizedAccessException

1。确保用户帐户具有必要的权限 要解决此问题,您可以:

为运行该服务的用户帐户授予必要的权限,以便其正常工作:

  • 确保用户拥有创建和管理所需的权限 事件句柄。这通常涉及授予用户帐户 SeCreateGlobalPrivilege 以及潜在的 SeIncreaseQuotaPrivilege 特权。

2。修改代码中的安全设置

如果您可以控制代码,则可以通过编程方式修改安全设置,以授予对事件句柄的适当访问权限。以下是如何修改 iDB2NamedEvent 方法以确保使用适当的安全设置创建事件句柄的示例:

 internal iDB2NamedEvent(string eventName)
{
    SecurityPermission securityPermission = new SecurityPermission(SecurityPermissionFlag.UnmanagedCode);
    waitHandle = null;
    string identity = (new SecurityIdentifier(WellKnownSidType.WorldSid, null).Translate(typeof(NTAccount)) as NTAccount).ToString();
    try
    {
        securityPermission.Assert();
        EventWaitHandleSecurity eventWaitHandleSecurity = new EventWaitHandleSecurity();
        EventWaitHandleAccessRule rule = new EventWaitHandleAccessRule(identity, EventWaitHandleRights.FullControl, AccessControlType.Allow);
        eventWaitHandleSecurity.AddAccessRule(rule);
        
        bool createdNew;
        waitHandle = new EventWaitHandle(initialState: false, EventResetMode.ManualReset, "CWB_MP_TI_EVENT", out createdNew, eventWaitHandleSecurity);
    }
    catch
    {
        CodeAccessPermission.RevertAssert();
        throw;
    }

    CodeAccessPermission.RevertAssert();
}

3.在 IIS 中使用应用程序池身份 对于 IIS,请确保应用程序池标识具有必要的权限:

  1. 打开 IIS 管理器。

  2. 选择运行 ASP.NET 应用程序的应用程序池

  3. 单击“高级设置...”。

  4. 在“流程模型”下,将“身份”更改为具有所需权限的帐户,或将其配置为使用您确保具有这些权限的自定义帐户。

4。作为本地系统运行 作为最后的手段,如果更改权限不可行,您可以继续在本地系统帐户下运行服务。但是,出于安全原因,通常不建议在本地系统下运行服务,除非绝对必要。

如果您仍然遇到任何错误,请告诉我。

© www.soinside.com 2019 - 2024. All rights reserved.