【问题标题】:Firebird - how to enumerate usersFirebird - 如何枚举用户
【发布时间】:2018-10-16 22:48:06
【问题描述】:

我们公司使用了更多使用 Firebird 数据库的应用程序。在某些安装中,我们使用安装在更多机器上的数据库服务。现在我正在尝试为所有这些集中用户管理。为此,我正在编写新的应用程序。我需要的是在 localhost 或网络中连接到选定的 Firebird 服务并枚举所有用户。传统上,“gsec”实用程序用于此目的。 “gsec”是 Firebird 安装的一部分。我可以像这样使用这个实用程序的命令行输出:

 user name                    uid   gid admin     full name
------------------------------------------------------------------------------------------------
SYSDBA                              0     0           Sql Server Administrator
TECHNICIAN                          0     0           Technician  Technician
TECHNIK                             0     0           Technik  Technik

但这对我来说似乎很麻烦。在 Firebird 的下一个版本中,文本输出的格式也可以改变。所以我宁愿直接使用位于 fbclient.dll 库中的 Firebird api。从 SysInternals 的 ProcessExplorer 实用程序中可以看出,“gsec”实用程序在内部使用 fbclient.dll。不幸的是,没有任何类型的文档。我所知道的是我应该在我的项目中包含 ibase.h 头文件。这个头文件的文档记录很差。我还下载了“gsec”实用程序的源代码,但它非常混乱。由于缺少 fbclient.dll 的导入库,该项目无法在 Visual Studio 2008 中编译。我曾尝试使用these 指令生成导入库,但失败了。

那么问题来了:如何使用客户端库fbclient.dll枚举firebird数据库机器中定义的用户?

【问题讨论】:

    标签: firebird


    【解决方案1】:

    借助 Firebird 3,您现在可以使用 SQL 查询用户。要查询用户,您需要是 SYSDBA 或具有 RDB$ADMIN 角色(否则您只能列出您自己的帐户),使用SEC$USERS 虚拟表:

    select SEC$USER_NAME, SEC$FIRST_NAME, SEC$MIDDLE_NAME, SEC$LAST_NAME, 
           SEC$ACTIVE, SEC$ADMIN, SEC$DESCRIPTION, SEC$PLUGIN 
    from SEC$USERS
    

    管理用户的早期选项,例如使用服务 API(如下所述)或 gsec 现在被认为已弃用(请参阅 Firebird 3 发行说明中的​​ SQL Features for Managing Access)。

    有此 API 的文档,请参阅作为 Interbase 6 文档集一部分的 API 指南,可从 Firebird website 下载。较新的功能通常没有完整的文档记录,但在过去 15 年中获取用户信息 (isc_info_svc_get_users) 并没有太大变化。

    API 指南的第 232 页专门记录了用户的检索(+ 第 221 页显示的一些代码):

    char spb_buffer[6], *spb = spb_buffer;
    char request_buffer[] = {
        isc_action_svc_display_user,
        isc_info_svc_get_users};
    char result_buffer[1024], *p = result_buffer;
    *spb++ = isc_info_svc_timeout;
    ADD_SPB_NUMERIC(spb, 60); /* 1 minute timeout */
    
    if (isc_service_query (
        status,
        &service_handle,
        NULL,
        spb - spb_buffer, spb_buffer,
        sizeof(request_buffer), request_buffer,
        sizeof(result_buffer), result_buffer))
    {
        isc_print_status(status);
        isc_service_detach(status, &svc_handle);
        return;
    }
    do
    {
        switch (*p++)
        {
        case isc_info_svc_get_users:
        {
            ISC_USHORT len, loop;
            ISC_ULONG id;
            char buffer[50], *buf = buffer;
            loop = (ISC_USHORT) isc_vax_integer (p, sizeof (ISC_USHORT));
            p += sizeof (ISC_USHORT);
            while (*p != isc_info_end)
            {
                switch (*p++)
                {
                case isc_spb_sec_username:
                    len = (ISC_USHORT) isc_vax_integer(p, sizeof(ISC_USHORT));
                    p += sizeof (ISC_USHORT);
                    strncpy (buf, p, len);
                    p += len;
                    buffer[len] = 0;
                    printf ("Username: %s\n", buffer);
                    loop -= (len + sizeof(ISC_USHORT)+1);
                    break;
                // Removed some information items for brevity
                case isc_spb_sec_groupid:
                    id = isc_vax_integer (p, sizeof (ISC_ULONG));
                    p += sizeof (ISC_ULONG);
                    printf ("Group ID: %d\n", id);
                    loop -= (len + sizeof(ISC_ULONG)+1);
                    break;
                case isc_spb_sec_userid:
                    id = isc_vax_integer (p, sizeof (ISC_ULONG));
                    p += sizeof (ISC_ULONG);
                    printf ("User ID: %d\n", id);
                    loop -= (len + sizeof(ISC_ULONG)+1);
                    break;
                default:
                    *x = *p;
                    break;
                } /* end switch */
            } /* end while */
            break;
        }
        // Other cases
    }
    

    【讨论】:

    • 方法 isc_service_query 无限期阻塞:-(。我已经使用 isc_service_attach 成功连接到 localhost 服务(使用 TCPView 实用程序可以看到连接)。
    • @truthseeker 你附加到“service_mgr”了吗?
    • localhost:service_mgr
    • @truthseeker 我通常通过有线协议工作,而不是通过客户端库。我会检查上面的代码是否缺少任何东西,不过可能需要几天时间。
    • ibphoenix.com/resources/documents/search/doc_180: "您必须在使用此服务之前启动服务 isc_action_svc_display_users。"也许这是个问题。
    【解决方案2】:

    您不是在编写 Firebird 版本。但是您可以使用服务 API (service_mgr) 来获取用户列表等。检查 isc_action_svc_display_userisc_info_svc_get_users

    【讨论】:

      猜你喜欢
      • 2010-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多