Firebird - 如何枚举用户

时间:2015-01-05 14:00:45

标签: firebird

我们公司使用更多与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。 “gsec”实用程序也使用内部fbclient.dll,可以在SysInternals的ProcessExplorer实用程序中看到。不幸的是,没有任何形式的文件。我所知道的是我应该将ibase.h头文件包含到我的项目中。这个头文件记录很差。我还下载了“gsec”实用程序的源代码,但它非常混乱。由于缺少fbclient.dll的导入库,因此无法在Visual Studio 2008中编译该项目。我曾尝试使用these指令生成导入库,但失败了。

所以问题是:如何使用客户端库fbclient.dll枚举firebird数据库机器中定义的用户?

2 个答案:

答案 0 :(得分:3)

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

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的文档,请参阅API指南,该指南是可从Firebird website下载的Interbase 6文档集的一部分。较新的功能通常没有详细记录,但获取用户信息(isc_info_svc_get_users)在过去15年中没有太大变化。

具体的用户检索记录在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
}

答案 1 :(得分:2)

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