Oracle
 sql >> база данни >  >> RDS >> Oracle

ORACLE. Удостоверяването с LDAP винаги връща -16

Ако просто искате да удостоверите потребител срещу LDAP, това е доста просто:

DECLARE

    ret NUMBER;     
    ld DBMS_LDAP.SESSION;
    SUCCESS INTEGER;

    ldap_host VARCHAR2(100) := 'host';
    ldap_port INTEGER := 389;

    userDn VARCHAR2(100) := 'OU=SERVICE_ACCOUNTS,OU=Users,OU=LT,OU=PB,DC=pan,DC=int';
    userPassword VARCHAR2(100) := 'secret';
    
BEGIN
    DBMS_LDAP.USE_EXCEPTION := TRUE;
    ld := DBMS_LDAP.INIT(ldap_host, ldap_port);
    DBMS_LDAP.USE_EXCEPTION := FALSE;

    SUCCESS := DBMS_LDAP.SIMPLE_BIND_S(ld, userDn, userPassword);
    IF SUCCESS = DBMS_LDAP.SUCCESS AND userPassword IS NOT NULL THEN
        DBMS_OUTPUT.PUT_LINE('Password is valid');
    ELSE
        DBMS_OUTPUT.PUT_LINE('Wrong password');
    END IF;

    ret := DBMS_LDAP.UNBIND_S(ld);

END;

Ако искате да правите заявки за атрибути на даден потребител, можете да погледнете този пример:

DECLARE

    SUBTYPE T_USER_ACCOUNT_CONTROL IS INTEGER;
    -- see https://support.microsoft.com/en-us/help/305144/how-to-use-the-useraccountcontrol-flags-to-manipulate-user-account-pro
    SKRIPT                                  CONSTANT T_USER_ACCOUNT_CONTROL := 1;
    ACCOUNTDISABLE                          CONSTANT T_USER_ACCOUNT_CONTROL := 2;
    HOMEDIR_REQUIRED                        CONSTANT T_USER_ACCOUNT_CONTROL := 8;
    LOCKOUT                                     CONSTANT T_USER_ACCOUNT_CONTROL := 16;
    PASSWD_NOTREQD                          CONSTANT T_USER_ACCOUNT_CONTROL := 32;
    PASSWD_CANT_CHANGE                  CONSTANT T_USER_ACCOUNT_CONTROL := 64;
    ENCRYPTED_TEXT_PWD_ALLOWED          CONSTANT T_USER_ACCOUNT_CONTROL := 128;
    TEMP_DUPLICATE_ACCOUNT              CONSTANT T_USER_ACCOUNT_CONTROL := 256;
    NORMAL_ACCOUNT                          CONSTANT T_USER_ACCOUNT_CONTROL := 512;
    INTERDOMAIN_TRUST_ACCOUNT           CONSTANT T_USER_ACCOUNT_CONTROL := 2048;
    WORKSTATION_TRUST_ACCOUNT           CONSTANT T_USER_ACCOUNT_CONTROL := 4096;
    SERVER_TRUST_ACCOUNT                    CONSTANT T_USER_ACCOUNT_CONTROL := 8192;
    DONT_EXPIRE_PASSWORD                    CONSTANT T_USER_ACCOUNT_CONTROL := 65536;
    MNS_LOGON_ACCOUNT                   CONSTANT T_USER_ACCOUNT_CONTROL := 131072;
    SMARTCARD_REQUIRED                  CONSTANT T_USER_ACCOUNT_CONTROL := 262144;
    TRUSTED_FOR_DELEGATION              CONSTANT T_USER_ACCOUNT_CONTROL := 524288;
    NOT_DELEGATED                           CONSTANT T_USER_ACCOUNT_CONTROL := 1048576;
    USE_DES_KEY_ONLY                        CONSTANT T_USER_ACCOUNT_CONTROL := 2097152;
    DONT_REQ_PREAUTH                        CONSTANT T_USER_ACCOUNT_CONTROL := 4194304;
    PASSWORD_EXPIRED                        CONSTANT T_USER_ACCOUNT_CONTROL := 8388608;
    TRUSTED_TO_AUTH_FOR_DELEGATION  CONSTANT T_USER_ACCOUNT_CONTROL := 16777216;
    PARTIAL_SECRETS_ACCOUNT             CONSTANT T_USER_ACCOUNT_CONTROL := 67108864;
    
    LDAP_USER CONSTANT VARCHAR2(255) := 'CN=UserName1,OU=SERVICE_ACCOUNTS,OU=Users,OU=LT,OU=PB,DC=pan,DC=int';
    LDAP_PASSWORD CONSTANT VARCHAR2(30) := 'secret';
    LDAP_SERVER CONSTANT VARCHAR2(30) := 'host';
    LDAP_PORT INTEGER := 389;

    userDn VARCHAR2(100) := 'CN=UserName2,OU=SERVICE_ACCOUNTS,OU=Users,OU=LT,OU=PB,DC=pan,DC=int';


    ld DBMS_LDAP.SESSION;
    ret NUMBER; 
    ldapEntry DBMS_LDAP.MESSAGE;    
    attrs DBMS_LDAP.STRING_COLLECTION;  
    ldapMessage DBMS_LDAP.MESSAGE;
    attribName VARCHAR2(256);
    berEelement DBMS_LDAP.BER_ELEMENT;
    info DBMS_LDAP.STRING_COLLECTION;
    
    pwdLastSet TIMESTAMP;
    expireDate TIMESTAMP
    
BEGIN
    
    attrs(1) := 'displayName';
    attrs(2) := 'userAccountControl';
    attrs(3) := 'pwdLastSet';

    ld := DBMS_LDAP.INIT(LDAP_SERVER, LDAP_PORT);
    ret := DBMS_LDAP.SIMPLE_BIND_S(ld, LDAP_USER, LDAP_PASSWORD);
    DBMS_LDAP.USE_EXCEPTION := FALSE;
    
    ret := DBMS_LDAP.SEARCH_S(
        ld => ld, 
        base => 'DC=pan,DC=int',
        SCOPE => DBMS_LDAP.SCOPE_SUBTREE,
        FILTER => '&(objectCategory=user)(distinguishedName='||userDn||')', 
        attrs => attrs,
        attronly => 0,
        res => ldapMessage);
    ldapEntry := DBMS_LDAP.FIRST_ENTRY(ld, ldapMessage);
    IF ldapEntry IS NULL THEN
        DBMS_OUTPUT.PUT_LINE('User "'||userDn||'" does not exist');
    ELSE
        WHILE ldapEntry IS NOT NULL LOOP        
            attribName := DBMS_LDAP.FIRST_ATTRIBUTE(ld, ldapEntry, berEelement);
            WHILE attribName IS NOT NULL LOOP     
                info := DBMS_LDAP.GET_VALUES(ld, ldapEntry, attribName);
                CASE attribName
                WHEN 'displayName' THEN 
                    DBMS_OUTPUT.PUT_LINE('Display Name = ' || info(info.FIRST));
                WHEN 'userAccountControl' THEN
                    IF SIGN(BITAND(ACCOUNTDISABLE, info(info.FIRST))) = 1 THEN
                        DBMS_OUTPUT.PUT_LINE('Account is disabled');
                    END IF;
                    
                    IF SIGN(BITAND(PASSWORD_EXPIRED, info(info.FIRST))) = 1 THEN
                        DBMS_OUTPUT.PUT_LINE('Password is expired');
                    END IF;                 
                WHEN 'pwdLastSet' THEN
                    pwdLastSet := (TIMESTAMP '1601-01-01 00:00:00 UTC' + info(info.FIRST)/1000/1000/10/60/60/24 * INTERVAL '1' DAY) AT LOCAL;
                    DBMS_OUTPUT.PUT_LINE('Password was changed at ' || TO_CHAR(pwdLastSet, 'yyyy-mm-dd hh24:mi:ss'));

                    -- Password life time is not available in LDAP. Check your company policy and calculate expire date accordingly, for example:
                    expireDate := pwdLastSet + INTERVAL '6' MONTH;
                    DBMS_OUTPUT.PUT_LINE('Your password will expire at ' || TO_CHAR(expireDate, 'yyyy-mm-dd hh24:mi:ss'));                  
                END CASE;       
                attribName := DBMS_LDAP.NEXT_ATTRIBUTE(ld, ldapEntry, berEelement);
            END LOOP;
            ldapEntry := DBMS_LDAP.NEXT_ENTRY(ld, ldapEntry);
        END LOOP;
        DBMS_LDAP.BER_FREE(berEelement, freebuf => 0);  
    END IF;
    ret := DBMS_LDAP.MSGFREE(ldapMessage);
    ret := DBMS_LDAP.UNBIND_S(ld);

end;

Актуализация

Направих грешка, когато казах „Времето на живот на паролата не е налично в LDAP“. Можете да го направите по този начин:

BEGIN

   dn := 'DC=pan,DC=int';
   attrs(1) := 'maxPwdAge';

    ld := DBMS_LDAP.INIT(LDAP_SERVER, LDAP_PORT);
    ret := DBMS_LDAP.SIMPLE_BIND_S(ld, LDAP_USER, LDAP_PASSWORD);
    DBMS_LDAP.USE_EXCEPTION := FALSE;

    ret := DBMS_LDAP.SEARCH_S(
        ld => ld, 
        base => 'DC=pan,DC=int',
        SCOPE => DBMS_LDAP.SCOPE_SUBTREE,
        FILTER => '&(objectCategory=domain)(distinguishedName='||dn||')', 
        attrs => attrs,
        attronly => 0,
        res => ldapMessage);
    -- You do not need a loop because you have only one single entry and one single attribute. Otherwise a loop would be required, see above.
    ldapEntry := DBMS_LDAP.FIRST_ENTRY(ld, ldapMessage);
    attribName := DBMS_LDAP.FIRST_ATTRIBUTE(ld, ldapEntry, berEelement);
    info := DBMS_LDAP.GET_VALUES(ld, ldapEntry, attribName);    

    DBMS_OUTPUT.PUT_LINE('Password life time = ' || -info(info.FIRST)/1000/1000/10/60/60/24 || ' days');

    DBMS_LDAP.BER_FREE(berEelement, freebuf => 0);  
    ret := DBMS_LDAP.MSGFREE(ldapMessage);
    ret := DBMS_LDAP.UNBIND_S(ld);

END;



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Проблем при сравнение на низове на Oracle PL/SQL

  2. Компилаторът pro*C на Oracle и gnu C (__builtin_va_list, __attribute__ и т.н.)

  3. Изпълнение на незабавна промяна на променливата за свързване на потребителя

  4. PLS-00306:грешен номер или типове аргументи в извикването на

  5. SEC_CASE_SENSTIVE_LOGON в 12c