DB2 9部署定制的安全性插件(3)

http://www.itjxue.com  2015-08-21 22:27  来源:未知  点击次数: 

  DB2 9 中 DB2 安全性插件的增强

 

  DB2 9 中对 DB2 安全性插件基础设施进行了很多增强,包括基于轻量级目录访问协议(Lightweight Directory Access Protocol,LDAP)的身份验证插件的输送、基于 LDAP 的组成员查找插件的输送、及 client connection details 的增强以包括对 TCP/IP 版本 6 和客户机操作系统平台信息的支持。

  可以从 DB2 LDAP 验证插件 下载受 IBM 支持的基于 LDAP 的身份验证插件和组成员查找插件。

  如果已经通过 TCP/IP 地址实现了连接限定,且您的公司正准备实现 TCP/IP 版本 6,则需要修改安全性插件,从而进行对应的操作。

  首先,需要从使用下面所列的版本 2 或 3 的连接详细信息结构(节选自 IBM 发布的头文件 db2secPlugin.h)开始。版本 2 和 3 的区别在于版本 3 还给出了客户机操作系统平台。

  清单 1. 客户机连接详细信息结构的新版本

  typedef struct db2sec_con_details_2

  {

  db2int32 clientProtocol; /* See SQL_PROTOCOL_ in sqlenv.h */

  db2Uint32 clientIPAddress; /* Set if protocol is TCPIP4 */

  db2Uint32 connect_info_bitmap;

  db2int32 dbnameLen;

  char dbname[DB2SEC_MAX_DBNAME_LENGTH + 1];

  db2Uint32 clientIP6Address[4];/* Set if protocol is TCPIP6 */

  } db2sec_con_details_2;

  typedef struct db2sec_con_details_3

  {

  db2int32 clientProtocol; /* See SQL_PROTOCOL_ in sqlenv.h */

  db2Uint32 clientIPAddress; /* Set if protocol is TCPIP4 */

  db2Uint32 connect_info_bitmap;

  db2int32 dbnameLen;

  char dbname[DB2SEC_MAX_DBNAME_LENGTH + 1];

  db2Uint32 clientIP6Address[4];/* Set if protocol is TCPIP6 */

  db2Uint32 clientPlatform; /* SQLM_PLATFORM_* from sqlmon.h */

  db2Uint32 _reserved[16];

  } db2sec_con_details_3;

  然后,在调用回调函数时,使用 DB2SEC_CON_DETAILS_VERSION_2 或 DB2SEC_CON_DETAILS_VERSION_3 来代替 DB2 V8.2 文档所建议的 DB2SEC_API_VERSION_1 或数字 1。例如,假定要使用连接详细信息版本 3;可以在插件中进行下面的回调:

  struct db2sec_con_details_3 con_struct3;

  rc = (getConDetails_fn)(DB2SEC_CON_DETAILS_VERSION_3, &con_struct3);

  由于在整个机构上使用 TCP/IP 版本 6 是一个较长的过程,因此 DB2 可能会遇到一些仍使用 TCP/IP 版本 4 的客户机或其他切换到 TCP/IP 版本 6 的客户机。为了帮助使用者区分客户机,结构中 clientProtocol 字段现在可以返回 SQL_PROTOCOL_TCPIP4 或 SQL_PROTOCOL_TCPIP6,用来指示客户机正在使用的 TCP/IP 协议是版本 4,还是版本 6。

  如果需要找到客户机的操作系统,则可以检查 DB2 通过回调函数返回到字段 clientPlatform 中的整数。整数到相应平台的映射如下(节选自 IBM 发布的头文件 sqlmon.h):

  #define SQLM_PLATFORM_UNKNOWN 0 /* Unknown platform */

  #define SQLM_PLATFORM_OS2 1 /* OS/2 */

  #define SQLM_PLATFORM_DOS 2 /* DOS */

  #define SQLM_PLATFORM_WINDOWS 3 /* Windows */

  #define SQLM_PLATFORM_AIX 4 /* AIX */

  #define SQLM_PLATFORM_NT 5 /* NT */

  #define SQLM_PLATFORM_HP 6 /* HP */

  #define SQLM_PLATFORM_SUN 7 /* Sun */

  #define SQLM_PLATFORM_MVS_DRDA 8 /* MVS (client via DRDA) */

  #define SQLM_PLATFORM_AS400_DRDA 9 /* AS400 (client via DRDA) */

  #define SQLM_PLATFORM_VM_DRDA 10 /* VM (client via DRDA) */

  #define SQLM_PLATFORM_VSE_DRDA 11 /* VSE (client via DRDA) */

  #define SQLM_PLATFORM_UNKNOWN_DRDA 12 /* Unknown DRDA Client */

  #define SQLM_PLATFORM_SNI 13 /* Siemens Nixdorf */

  #define SQLM_PLATFORM_MAC 14 /* Macintosh Client */

  #define SQLM_PLATFORM_WINDOWS95 15 /* Windows 95 */

  #define SQLM_PLATFORM_SCO 16 /* SCO */

  #define SQLM_PLATFORM_SGI 17 /* Silicon Graphic */

  #define SQLM_PLATFORM_LINUX 18 /* Linux */

  #define SQLM_PLATFORM_DYNIX 19 /* DYNIX/ptx */

  #define SQLM_PLATFORM_AIX64 20 /* AIX 64 bit */

  #define SQLM_PLATFORM_SUN64 21 /* Sun 64 bit */

  #define SQLM_PLATFORM_HP64 22 /* HP 64 bit */

  #define SQLM_PLATFORM_NT64 23 /* NT 64 bit */

  #define SQLM_PLATFORM_LINUX390 24 /* Linux for S/390 */

  #define SQLM_PLATFORM_LINUXZ64 25 /* Linux for z900 */

  #define SQLM_PLATFORM_LINUXIA64 26 /* Linux for IA64 */

  #define SQLM_PLATFORM_LINUXPPC 27 /* Linux for PPC */

  #define SQLM_PLATFORM_LINUXPPC64 28 /* Linux for PPC64 */

  #define SQLM_PLATFORM_OS390 29 /* OS/390 Tools (CC, DW) */

  #define SQLM_PLATFORM_LINUXX8664 30 /* Linux for x86-64 */

  #define SQLM_PLATFORM_HPIA 31 /* HP-UX Itanium 32bit */

  #define SQLM_PLATFORM_HPIA64 32 /* HP-UX Itanium 64bit */

  下面是示例代码片断,其中阻塞了数据库服务器上的回路连接:

  清单 2. 来自本系列第 2 部分的连接限定代码

  /* If the connection is not local */

  if (!(con_struct.connect_info_bitmap & DB2SEC_CONNECTION_ISLOCAL))

  {

  struct hostent* hostinfo;

  char hostname[256];

  int* firstaddr;

  /* Get the address of the machine restricted */

  gethostname(hostname, sizeof(hostname));

  hostinfo = gethostbyname(hostname);

  firstaddr = (int *)*(hostinfo->h_addr_list);

  /* If the client IP address is the restricted one */

  if (*firstaddr == con_struct.clientIPAddress)

  {

  /* We won't allow behavoir to connect through this IP address */

  if (0 == strcmp(userid, "beauvoir"))

  return DB2SEC_PLUGIN_CONNECTION_DISALLOWED;

  }

  }

  为了使用 TCP/IP 版本 6,需要修改为以下代码:

  清单 3. 使用 IP V6 的连接限定代码

  if (!(con_struct3.connect_info_bitmap & DB2SEC_CONNECTION_ISLOCAL))

  {

  struct addrinfo* pAddr;

  /* find the local IP address to compare it with the one retrieved */

  if ((con_struct3.clientProtocol == SQL_PROTOCOL_TCPIP6) &&

  (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)con_struct3.clientIP6Address)))

  {

  /* Comment out the following line of code if your database server is not */

  /* running on MS Windows */

  aiHints.ai_flags = AI_ALL | AI_V4MAPPED;

  }

  else

  {

  aiHints.ai_flags = AI_PASSIVE;

  }

  aiHints.ai_family = (con_struct3.clientProtocol == SQL_PROTOCOL_TCPIP6)?

  AF_INET6 : AF_INET;

  aiHints.ai_socktype = SOCK_STREAM;

  aiHints.ai_protocol = IPPROTO_TCP;

  err = getaddrinfo(hostname, NULL, &aiHints, &aiList);

  if (err)

  {

  Print("getaddrinfo error: %d\n", err);

  return DB2SEC_PLUGIN_CONNECTION_DISALLOWED;

  }

  /* compare the IPs */

  if (SQL_PROTOCOL_TCPIP6 == con_struct3.clientProtocol)

  {

  pAddr = aiList;

  while (pAddr)

  {

  struct sockaddr_in6* s = (struct sockaddr_in6*)pAddr->ai_addr;

  struct in6_addr *src = (struct in6_addr*)&s->sin6_addr;

  struct in6_addr *dst =

  (struct in6_addr*)&con_struct3.clientIP6Address;

  /* check if address verified is the same format as the address

  * sent by the client: compare only IPv6 format address with

  * IPv6 ones or IPv6 mapped IPv4 with the same type */

  if ((*(db2Uint32*)(&s->sin6_addr.s6_addr[0]) ==

  con_struct3.clientIP6Address[0]) &&

  (*(db2Uint32*)(&s->sin6_addr.s6_addr[4]) ==

  con_struct3.clientIP6Address[1]) &&

  (*(db2Uint32*)(&s->sin6_addr.s6_addr[8]) ==

  con_struct3.clientIP6Address[2]) &&

  (*(db2Uint32*)(&s->sin6_addr.s6_addr[12])==

  con_struct3.clientIP6Address[3]))

  {

  /* don't allow beauvoir to connect through this ip address */

  if (0 == strcmp(userid, "beauvoir"))

  {

  return DB2SEC_PLUGIN_CONNECTION_DISALLOWED;

  }

  else

  {

  break;

  }

  }

  pAddr = pAddr->ai_next;

  } /* while (pAddr) */

  }

  else /* This else clause is need if you have a mix v4 and v6 environment */

  {

  /* TCPIP4 */

  struct sockaddr_in* s = (struct sockaddr_in*)aiList->ai_addr;

  if (s->sin_addr.s_addr == con_struct3.clientIPAddress)

  {

  /* don't allow beauvoir to connect through this ip address */

  if (0 == strcmp(userid, "beauvoir"))

  return DB2SEC_PLUGIN_CONNECTION_DISALLOWED;

  }

  }

  freeaddrinfo(aiList);

  }

  结束语

  本文给出了 DB2 9 中 DB2 安全插件的增强信息,详细阐述了安全性插件的职责。本文还提出了基于这些职责的最小完备测试列表。现在您应知道如何使用安全性插件 loader 来测试定制的安全性插件,该 loader 可以在 下载 部分中找到。

(责任编辑:IT教学网)

更多

推荐数据库文章