sql >> Databasteknik >  >> RDS >> Oracle

ORAKEL. Autentisering med LDAP returnerar alltid -16

Om du bara vill autentisera en användare mot LDAP är det ganska enkelt:

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;

Om du vill fråga efter attribut för en given användare kan du ta en titt på detta exempel:

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;

Uppdatera

Jag gjorde ett misstag när jag säger "Lösenordets livslängd är inte tillgängligt i LDAP". Du kan fråga det så här:

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. Vad är det kanoniska sättet att hämta en post från en MySQL-databas som har det minsta/största fältet?

  2. kan inte få ut parameter från lagrad procedur med php

  3. Fel syntax nära nyckelordet "med".

  4. Hur returnerar jag en lista med värden istället för en sträng när jag frågar efter en Oracle-databas med XPath?