Oracle PL/SQL管理LDAP服务器(DBMS_LDAP包的使用)

了解LDAP

LDAP是Light Directory Access Protocol轻量级目录访问协议的简称,LDAP与数据库有很大的区别,它的数据是树状的,而且每个节点的属性也比较固定。
LDAP协议中用dn表示一条记录的位置,dc表示一条记录所属区域,ou表示一条记录所属组织,cn表示一条记录的名称,uid表示一条记录的ID,其中dn是根据dc、ou、cn或uid的组合来表示的,对于某条记录dn是唯一的,但是dc、ou、cn及uid可以有多个,
例如,常见的用户表示:

dn:cn=张三,cn=users,dc=google,dc=cn
这条记录中dc和cn都有两个。

DBMS_LDAP包

PL/SQL中通过DBMS_LDAP包来管理LDAP服务器。
在默认情况下,DBMS_LDAP包并不载入,需要使用以下sql:

SQL> CONNECT / AS SYSDBA
SQL> @$ORACLE_HOME/rdbms/admin/catldap.sql

数据类型:

SESSION
用于保存LDAP会话的句柄,几乎所有DBMS_LDAP中的函数都需要此类型做参数。

MESSAGE
用于接收结果集. 用于所有关于记录属性和值的函数(如接收搜索函数返回的记录集合)。

MOD_ARRAY
用于modify_s() or add_s()操作的待修改或新增的数组。

TIMEVAL
用于设置LDAP API函数的超时时间。

BER_ELEMENT
保存BER 结构的句柄,用于引入消息的解码。

STRING_COLLECTION
可传给LDAP服务器的VARCHAR2字符串集合。

BINVAL_COLLECTION
RAW data集合,为二进制形式。

BERVAL_COLLECTION
BERVAL数据集合。

BLOB_COLLECTION
BLOB data集合。

函数:
1、init 
init() 用户初始化一个LDAP服务器会话。 本操作将会创建一个LDAP服务器的连接,成功后将返回一个SESSION。

FUNCTION init ( 
    hostname IN VARCHAR2, --服务器地址

    portnum IN PLS_INTEGER --连接端口
)
RETURN SESSION;

2、simple_bind_s

本函数根据特定的用户和密码登陆LDAP服务器,成功后返回PLS_INTEGER类型。

FUNCTION simple_bind_s ( 
    ld IN SESSION, --init返回的session

    dn IN VARCHAR2,--登陆用户的dn passwd IN VARCHAR2 --登陆用户的密码
)
RETURN PLS_INTEGER;

3、unbind_s

关闭LDAP会话。

FUNCTION unbind_s ( 
    ld IN OUT SESSION --init返回的session
)
RETURN PLS_INTEGER

4、create_mod_array

创建一个MOD_ARRAY,用于modify_s()或add_s()。执行成功返回MOD_ARRAY,失败返回NULL。

FUNCTION create_mod_array ( 
    num IN PLS_INTEGER --数组个数
)
RETURN MOD_ARRAY;

5、populate_mod_array
为MOD_ARRAY集合中的一个元素设置属性及操作方式。根据modval值类型的不同,过程有一下三钟方式:

PROCEDURE populate_mod_array (

    modptr IN DBMS_LDAP.MOD_ARRAY,--待操作的MOD_ARRAY

    mod_op IN PLS_INTEGER,--操作类型

    mod_type IN VARCHAR2, --属性

    modval IN DBMS_LDAP.STRING_COLLECTION --值(字符型)

);

PROCEDURE populate_mod_array ( 
    modptr IN DBMS_LDAP.MOD_ARRAY,

    mod_op IN PLS_INTEGER,

    mod_type IN VARCHAR2,

    modbval IN DBMS_LDAP.BERVAL_COLLECTION --BERVAL类型

);

PROCEDURE populate_mod_array (
    modptr IN DBMS_LDAP.MOD_ARRAY,
    mod_op IN PLS_INTEGER,
    mod_type IN VARCHAR2,
    modbval IN DBMS_LDAP.BLOB_COLLECTION --BLOB类型
);

mod_op可为:
修改 dbms_ldap.MOD_REPLACE
增加 dbms_ldap.MOD_ADD
删除 dbms_ldap.MOD_DELETE

6、modify_s
修改一个已经存在的记录。

FUNCTION modify_s ( 
    ld IN DBMS_LDAP.SESSION, --session

    entrydn IN VARCHAR2, --待修改的记录dn

    modptr IN DBMS_LDAP.MOD_ARRAY --待修改的属性 MOD_ARRAY

)
RETURN PLS_INTEGER;

7、add_s
向LDAP服务器添加一条记录。

FUNCTION add_s ( 
    ld IN DBMS_LDAP.SESSION, --session

    entrydn IN VARCHAR2, --要新增的记录dn

    modptr IN DBMS_LDAP.MOD_ARRAY --属性MOD_ARRAY

)
RETURN PLS_INTEGER;

8、delete_s
删除一条记录。

FUNCTION delete_s ( 
    ld IN SESSION, --session

    entrydn IN VARCHAR2 --要删除的记录dn

)

9、free_mod_array
是否之前创建的MOD_ARRAY

PROCEDURE free_mod_array ( 
    modptr IN DBMS_LDAP.MOD_ARRAY --MOD_ARRAY
);

10、其他
其他函数起参照:
http://docs.huihoo.com/oracle/docs/B14099_19/idmanage.1012/b14087/dbmsldap_ref.htm

例程(LDAP服务器为ORACLE的OID)

这是一个相对完整的ORACLE应用服务用户管理例程,实现了用户的新增,密码初始化,解锁,禁用,启用及删除等操作。本程序可在PL/SQL Developer测试窗口中运行,若要使用本程序,需修改变量ldap_host,ldap_port,ldap_user,ldap_passwd,ldap_base的初始值。

隐藏行号 复制代码 PL/SQL代码
  1. DECLARE
  2.   retval      PLS_INTEGER; --返回
  3.   my_session  dbms_ldap.session;
  4.   my_dn       VARCHAR(256);
  5.   ldap_host   VARCHAR(256);
  6.   ldap_port   VARCHAR(256);
  7.   ldap_user   VARCHAR(256);
  8.   ldap_passwd VARCHAR(256);
  9.   ldap_base   VARCHAR(256);
  10.   mod_user    VARCHAR(256); --需要操作的用户帐号
  11.   mod_type    VARCHAR(1); --操作类型 0-初始化密码 1-解锁 2-禁用 3--启用  4-删除 5-新增 
  12.   mod_attr    VARCHAR(256);
  13.   my_array    dbms_ldap.mod_array;
  14.   my_vals     dbms_ldap.string_collection;
  15.   my_entry    dbms_ldap.message;
  16.   my_message  dbms_ldap.message;
  17.   my_attrs    dbms_ldap.string_collection;
  18. BEGIN
  19.   retval      := -1;
  20.   ldap_host   := '127.0.0.1'; --LDAP服务器IP地址
  21.   ldap_port   := '389'; --LDAP服务器端口
  22.   ldap_user   := 'cn=admin,cn=users,dc=test,dc=cn'; --管理员dn
  23.   ldap_passwd := '111111'; --管理员密码
  24.   ldap_base   := 'cn=Users,dc=test,dc=cn';
  25.   dbms_ldap.use_exception := TRUE; --打开异常
  26.   :err_msg                := '';
  27.   --打开会话
  28.   my_session := dbms_ldap.init(ldap_host, ldap_port);
  29.   --登陆管理员
  30.   retval := dbms_ldap.simple_bind_s(my_session, ldap_user, ldap_passwd);
  31.   dbms_output.put_line('初始化会话成功!');
  32.   mod_user := 'cn=' || :帐号 || ',' || ldap_base;
  33.   mod_type := :操作类型;
  34.   IF mod_type IN ('0', '2', '3') THEN
  35.     CASE
  36.       WHEN mod_type = '0' THEN
  37.         --如果用户不输入密码则初始化密码为当天日期
  38.         my_vals(1) := :密码;
  39.         IF my_vals(1) = '' OR my_vals(1) IS NULL THEN
  40.           my_vals(1) := to_char(SYSDATE, 'yymmdd');
  41.         END IF;
  42.         mod_attr := 'userpassword';
  43.       WHEN mod_type = '2' THEN
  44.         --禁用用户
  45.         my_vals(1) := 'disabled';
  46.         mod_attr := 'orclisenabled';
  47.       WHEN mod_type = '3' THEN
  48.         --启用用户
  49.         my_vals(1) := 'enabled';
  50.         mod_attr := 'orclisenabled';
  51.       ELSE
  52.         NULL;
  53.     END CASE;
  54.   /*
  55.      属性修改步骤:先创建一个MOD_ARRAY,再调用populate_mod_array填入操作类型和值,然后调用 modify_s实现修改,最后用free_mod_array释放MOD_ARRAY。
  56.     */
  57.     my_array := dbms_ldap.create_mod_array(1);
  58.     dbms_ldap.populate_mod_array(my_array, dbms_ldap.mod_replace, mod_attr, my_vals);
  59.     retval := dbms_ldap.modify_s(my_session, mod_user, my_array);
  60.   
  61.     :err_msg := :帐号 || ' 修改 ' || mod_attr || ' 属性' || '为' || my_vals(1);
  62.     dbms_ldap.free_mod_array(my_array);
  63.   ELSIF mod_type = '1' THEN
  64.     --解锁
  65.     my_vals(1) := '1';
  66.     mod_attr := 'orclpwdaccountunlock';
  67.   
  68.     my_array := dbms_ldap.create_mod_array(1);
  69.     dbms_ldap.populate_mod_array(my_array, dbms_ldap.mod_add, mod_attr, my_vals);
  70.     retval := dbms_ldap.modify_s(my_session, mod_user, my_array);
  71.   
  72.     :err_msg := :帐号 || ' 解锁成功 ';
  73.   ELSIF mod_type = '4' THEN
  74.     --删除用户
  75.     retval   := dbms_ldap.delete_s(my_session, mod_user);
  76.     :err_msg := :帐号 || '删除成功!';
  77.   ELSIF mod_type = '5' THEN
  78.     --新增用户 
  79.     my_array := dbms_ldap.create_mod_array(14);
  80.     my_vals(1) := :帐号;
  81.     dbms_ldap.populate_mod_array(my_array, dbms_ldap.mod_add, 'cn', my_vals);
  82.   
  83.     dbms_ldap.populate_mod_array(my_array, dbms_ldap.mod_add, 'uid', my_vals);
  84.     my_vals(1) := :姓名;
  85.     dbms_ldap.populate_mod_array(my_array, dbms_ldap.mod_add, 'sn', my_vals);
  86.   
  87.     my_vals(1) := '111111';
  88.     dbms_ldap.populate_mod_array(my_array, dbms_ldap.mod_add, 'userpassword', my_vals);
  89.     my_vals(1) := substr(:帐号, 1, 4);
  90.     dbms_ldap.populate_mod_array(my_array, dbms_ldap.mod_add, 'mail', my_vals);
  91.     my_vals(1) := 'top';
  92.     my_vals(2) := 'person';
  93.     my_vals(3) := 'organizationalPerson';
  94.     my_vals(4) := 'inetOrgPerson';
  95.     my_vals(5) := 'orcluser';
  96.     my_vals(6) := 'orcluserv2';
  97.     dbms_ldap.populate_mod_array(my_array, dbms_ldap.mod_add, 'objectclass', my_vals);
  98.   
  99.     retval := dbms_ldap.add_s(my_session, mod_user, my_array);
  100.     dbms_ldap.free_mod_array(my_array);
  101.     :err_msg := '用户新增完成! ' || :姓名 || '(' || :帐号 || ')';
  102.   ELSE
  103.     :err_msg := '操作类型错误!请输入:0-初始化密码 1-解锁 2-禁用 3--启用  4-删除 5-新增';
  104.   END IF;
  105.   --获取姓名属性
  106.   IF mod_type <> '4' THEN
  107.     my_attrs(1) := '*';
  108.     retval := dbms_ldap.search_s(my_session,
  109.                                  mod_user,
  110.                                  dbms_ldap.scope_subtree,
  111.                                  'objectclass=*',
  112.                                  my_attrs,
  113.                                  0,
  114.                                  my_message);
  115.     retval := dbms_ldap.count_entries(my_session, my_message);
  116.     IF retval > 0 THEN
  117.       my_entry := dbms_ldap.first_entry(my_session, my_message);
  118.       my_vals  := dbms_ldap.get_values(my_session, my_entry, 'sn');
  119.       :姓名    := my_vals(my_vals.FIRST);
  120.     ELSE
  121.       :err_msg := '没有找到用户:' || :帐号;
  122.     END IF;
  123.   END IF;
  124.   retval := dbms_ldap.unbind_s(my_session);
  125. EXCEPTION
  126.   WHEN OTHERS THEN
  127.     :err_msg := 'ERR:' || to_char(SQLCODE) || ' ' || SQLERRM;
  128. END;

你可能感兴趣的:(程序设计)