LDAP Authentication and Authorization: PHP

Blah

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
<?php
    error_reporting(0);
    #=== FUNCTION ==================================================================
    #      NAME: ldapAuthenticationAndAuthorizationWithAttributes
    #      PARAMETERS:
    #                    $strLDAPHost                   String  LDAP Server URI
    #                    $strUIDAttr                    String  Schema attribute for user ID search
    #                    $strSystemUser                 String  System credential username
    #                    $strSystemPassword             String  System credential password
    #                    $strUserBaseDN                 String  User search LDAP base DN
    #                    $strLogonUserID                String  Input user ID
    #                    $strLogonUserPassword          String  Input user password
    #                    $arrayAttrsToReturn            String  Attributes to be returned
    #                    $strGroupBaseDN                String  (optional) Group search LDAP base DN
    #                    $strGroupNamingAttribute       String  (optional) Schema attribute for group search
    #                    $strMembershipAttr             String  (optional) Schema attribute for group membership
    #                    $strAuthGroup                  String  (optional) Group name
    #     DESCRIPTION: Verify authentication and authorization against AD server.a
    #
    #     RETURNS: array(BindReturnCode, Authorized, array(returnValues))
    #                        BindReturnCode:    -1 indicates LDAP connection failure, -2 indicates system account auth failed, -3 indicates user auth not attempted, >=0 is IANA-registered resultCode values (https://www.iana.org/assignments/ldap-parameters/ldap-parameters.xml#ldap-parameters-6)
    #                           NOTE: 0 is successful authentication in IANA-registered resultCode
    #                        Authorized:        0 authorization not attempted, -1 is not a member of the located group, 1 is member of the located group
    #                       arrayUserAttributeValues    Array with values of $arrayAttrsToReturn
    #
    #     USAGE: $arrayUserAuthorized = ldapAuthenticationAndAuthorizationWithAttributes("ldaps://ad.example.com","sAMAccountName","ldapquery@example.com", "Sy5t3mP@ssw0rdG03sH3re", "ou=example,dc=example,dc=com", $strInputUserName, $strInputUserPassword, array('givenName', 'sn'), "ou=securitygroups,dc=example,dc=com","cn", "member", "LJRTestGroup")
    #===============================================================================
    function ldapAuthenticationAndAuthorizationWithAttributes($strLDAPHost,$strUIDAttr, $strSystemUser, $strSystemPassword, $strUserBaseDN, $strLogonUserID, $strLogonUserPassword, $arrayAttrsToReturn, $strGroupBaseDN=null, $strGroupNamingAttribute=null, $strMembershipAttr=null, $strAuthGroup=null){
        $arrayAuthResults = array();
        $arrayUserAttributeValues = array();
        // Validate password is not null, otherwise directory servers implementing unauthenticated bind (https://tools.ietf.org/html/rfc4513#section-5.1.2) will return 0 on auth attempts with null password
        if( strlen($strLogonUserPassword) < 1){
            $arrayAuthResults['BindReturnCode'] = -3;
            $arrayAuthResults['Authorized'] = -1;
        }
        else{
            // Connect to the LDAP directory for system ID queries
            $systemDS = ldap_connect($strLDAPHost);
            ldap_set_option($systemDS, LDAP_OPT_PROTOCOL_VERSION, 3);
 
            if ($systemDS) {
                // Bind with the system ID and find $strLogonUserID FQDN
                $systemBind = ldap_bind($systemDS, $strSystemUser, $strSystemPassword);
 
                if(ldap_errno($systemDS) == 0){
                    $strLDAPFilter="(&($strUIDAttr=$strLogonUserID))";
                    $result=ldap_search($systemDS,$strUserBaseDN,$strLDAPFilter, $arrayAttrsToReturn);
 
                    $entry = ldap_first_entry($systemDS, $result);
 
                    $strFoundUserFQDN= ldap_get_dn($systemDS, $entry);
 
                    if($strFoundUserFQDN){
                        $userDS = ldap_connect($strLDAPHost);
                        ldap_set_option($userDS, LDAP_OPT_PROTOCOL_VERSION, 3);
 
                        $userBind = ldap_bind($userDS, $strFoundUserFQDN, $strLogonUserPassword);
                        $arrayAuthResults['BindReturnCode'] = ldap_errno($userDS);
 
                        ldap_close($userDS);
 
                        if($arrayAuthResults['BindReturnCode'] == 0){
                            $objFoundUser = ldap_get_entries($systemDS, $result);
                            for($arrayAttrsToReturn as $strAttributeName){
                                $arrayUserAttributeValues[$strAttributeName] = $objFoundUser[0][$strAttributeName];
 
                            }
                            $arrayAuthResults['AttributeValues'] = $arrayUserAttributeValues;
                            //////////////////////////////////////////////////////////////////////////////////////
                            // If an auth group has been supplied, verify authorization
                            //////////////////////////////////////////////////////////////////////////////////////
                            if($strAuthGroup){
                                // Escapes in DN need to be double-escaped or bad search filter error is encountered
                                $strGroupQuery = "(&($strGroupNamingAttribute=$strAuthGroup)($strMembershipAttr=" . str_replace("\\","\\\\", $strFoundUserFQDN) . "))";
 
                                $groupResult = ldap_search($systemDS,$strGroupBaseDN, $strGroupQuery);
                                $authorisedState = ldap_count_entries($systemDS ,$groupResult);
 
                                // If a group matching the filter is found, the user is authorised
                                if($authorisedState == 1){
                                    $arrayAuthResults['Authorized'] = 1;
                                }
                                // Otherwise the user is not a member of the group and is not authorised
                                else{
                                    $arrayAuthResults['Authorized'] = -1;
                                }
                            }
                            else{
                                $arrayAuthResults['Authorized'] = 0;
                            }
                            //////////////////////////////////////////////////////////////////////////////////////
                            ldap_close($systemDS);
                        }
                        // If the bind failed, the user has not logged in successfully so they cannot be authorized
                        else{
                            $arrayAuthResults['Authorized'] = -1;
 
                            ldap_close($systemDS);
                            ldap_close($userDS);
                        }
                    }
                    // User not found in directory
                    else{
                        $arrayAuthResults['BindReturnCode'] = 32;
                        $arrayAuthResults['Authorized'] = -1;
                    }
                }
                // system bind failed
                else{
                    $arrayAuthResults['BindReturnCode'] = -2;
                    $arrayAuthResults['Authorized'] = -1;
                    ldap_close($systemDS);
                }
            }
            // ldap connection failed
            else{
                $arrayAuthResults['BindReturnCode'] = -1;
                $arrayAuthResults['Authorized'] = -1;
            }
        }
        return $arrayAuthResults;
    }
 
    print "User password not supplied:\n";
    $arrayNullPassword = array();
    $arrayNullPassword = ldapAuthenticationAndAuthorizationWithAttributes("ldaps://ad.example.com","sAMAccountName","ldapquery@example.com", "Sy5t3mP@ssw0rdG03sH3re", "ou=example,dc=example,dc=com", "e0012345", '');
    var_dump($arrayNullPassword);
 
    print "Bad password:\n";
    $arrayBadPassword = array();
    $arrayBadPassword = ldapAuthenticationAndAuthorizationWithAttributes("ldaps://ad.example.com","sAMAccountName","ldapquery@example.com", "Sy5t3mP@ssw0rdG03sH3re", "ou=example,dc=example,dc=com", "e0012345", 'N0tTh3P@s5w0rd',"ou=SecurityGroups,dc=example,dc=com","cn", "member");
    var_dump($arrayBadPassword);
 
    print "\nInvalid user:\n";
    $arrayUserNotInDirectory = array();
    $arrayUserNotInDirectory = ldapAuthenticationAndAuthorizationWithAttributes("ldaps://ad.example.com","sAMAccountName","ldapquery@example.com", "Sy5t3mP@ssw0rdG03sH3re", "ou=example,dc=example,dc=com", "xe0012345", 'xDoesN0tM@tt3r');
    var_dump($arrayUserNotInDirectory);
 
    print "\nGood password without authorization:\n";
    $arrayUserAuthenticated = array();
    $arrayUserAuthenticated = ldapAuthenticationAndAuthorizationWithAttributes("ldaps://ad.example.com","sAMAccountName","ldapquery@example.com", "Sy5t3mP@ssw0rdG03sH3re", "ou=example,dc=example,dc=com", "e0012345", 'Us3rP@s5w0rdG035H3re|Us3rP@s5w0rdG035H3re');
    var_dump($arrayUserAuthenticated);
 
    print "\nGood password with authorized user:\n";
    $arrayUserAuthorized = array();
    $arrayUserAuthorized = ldapAuthenticationAndAuthorizationWithAttributes("ldaps://ad.example.com","sAMAccountName","ldapquery@example.com", "Sy5t3mP@ssw0rdG03sH3re", "ou=example,dc=example,dc=com", "e0012345", 'Us3rP@s5w0rdG035H3re|Us3rP@s5w0rdG035H3re',"ou=SecurityGroups,dc=example,dc=com","cn", "member", "cfyP_Unix_UnixUsers");
    var_dump($arrayUserAuthorized);
 
    print "\nGood password with unauthorized user:\n";
    $arrayUserNotAuthorized = array();
    $arrayUserNotAuthorized = ldapAuthenticationAndAuthorizationWithAttributes("ldaps://ad.example.com","sAMAccountName","ldapquery@example.com", "Sy5t3mP@ssw0rdG03sH3re", "ou=example,dc=example,dc=com", "e0012345", 'Us3rP@s5w0rdG035H3re|Us3rP@s5w0rdG035H3re',"ou=SecurityGroups,dc=example,dc=com","cn", "member", "WIN AM Team West");
    var_dump($arrayUserNotAuthorized);
 
    print "\nBad system account:\n";
    $arrayBadSystemCred = array();
    $arrayBadSystemCred = ldapAuthenticationAndAuthorizationWithAttributes("ldaps://ad.example.com","sAMAccountName","ldapquery@example.com", "xSy5t3mP@ssw0rdG03sH3re", "ou=example,dc=example,dc=com", "e0012345", 'Us3rP@s5w0rdG035H3re|Us3rP@s5w0rdG035H3re');
    var_dump($arrayBadSystemCred);
 
?>

Leave a Reply

Your email address will not be published. Required fields are marked *