Subversion Repositories php_utils

Rev

Rev 24 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
11 daniel-mar 1
<?php
2
 
3
/*
4
 * VtsLDAPUtils - Simple LDAP helper functions
5
 * Copyright 2021 Daniel Marschall, ViaThinkSoft
6
 * Revision: 2021-06-11
7
 *
8
 * Licensed under the Apache License, Version 2.0 (the "License");
9
 * you may not use this file except in compliance with the License.
10
 * You may obtain a copy of the License at
11
 *
12
 *     http://www.apache.org/licenses/LICENSE-2.0
13
 *
14
 * Unless required by applicable law or agreed to in writing, software
15
 * distributed under the License is distributed on an "AS IS" BASIS,
16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
 * See the License for the specific language governing permissions and
18
 * limitations under the License.
19
 */
20
 
21
class VtsLDAPUtils {
22
 
23
        protected $conn = null;
24
 
25
        private static function _L($str, ...$sprintfArgs) {
26
                if (function_exists('_L')) {
27
                        return _L($str, $sprintfArgs);
28
                } else {
29
                        return my_vsprintf($str, $sprintfArgs);
30
                }
31
        }
32
 
33
        public static function getString($ldap_userinfo, $attributeName) {
34
                $ary = self::getArray($ldap_userinfo, $attributeName);
35
                return implode("\n", $ary);
36
        }
37
 
38
        public static function getArray($ldap_userinfo, $attributeName) {
39
                $ary = array();
40
                if (isset($ldap_userinfo[$attributeName])) {
41
                        $cnt = $ldap_userinfo[$attributeName]['count'];
42
                        for ($i=0; $i<$cnt; $i++) {
43
                                $ary[] = $ldap_userinfo[$attributeName][$i];
44
                        }
45
                }
46
                return $ary;
47
        }
48
 
49
        public function isMemberOfRec($userDN, $groupDN) {
50
 
51
                if (isset($userDN['dn'])) $userDN = $userDN['dn'];
52
                if (isset($groupDN['dn'])) $groupDN = $groupDN['dn'];
53
 
54
                if (!$this->conn) throw new Exception('LDAP not connected');
55
                $res = ldap_read($this->conn, $groupDN, "(objectClass=*)");
56
                if (!$res) return false;
57
                $entries = ldap_get_entries($this->conn, $res);
58
                if (!isset($entries[0])) return false;
59
                if (!isset($entries[0]['member'])) return false;
60
                if (!isset($entries[0]['member']['count'])) return false;
61
                $cntMember = $entries[0]['member']['count'];
62
                for ($iMember=0; $iMember<$cntMember; $iMember++) {
63
                        $groupOrUser = $entries[0]['member'][$iMember];
64
                        if (strtolower($groupOrUser) == strtolower($userDN)) return true;
65
                        if ($this->isMemberOfRec($userDN, $groupOrUser)) return true;
66
                }
67
                return false;
68
        }
69
 
70
        public function __destruct() {
71
                $this->disconnect();
72
        }
73
 
74
        public function disconnect() {
75
                if ($this->conn) {
76
                        //ldap_unbind($this->conn); // commented out because ldap_unbind() kills the link descriptor
77
                        ldap_close($this->conn);
78
                        $this->conn = null;
79
                }
80
        }
81
 
82
        public function connect($cfg_ldap_server, $cfg_ldap_port) {
83
                $this->disconnect();
84
 
85
                // Connect to the server
86
                if (!empty($cfg_ldap_port)) {
87
                        if (!($ldapconn = @ldap_connect($cfg_ldap_server, $cfg_ldap_port))) throw new Exception(self::_L('Cannot connect to LDAP server'));
88
                } else {
89
                        if (!($ldapconn = @ldap_connect($cfg_ldap_server))) throw new Exception(self::_L('Cannot connect to LDAP server'));
90
                }
91
                ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3);
92
                ldap_set_option($ldapconn, LDAP_OPT_REFERRALS, 0);
93
 
94
                $this->conn = $ldapconn;
95
        }
96
 
97
        public function login($username, $password) {
98
                return @ldap_bind($this->conn, $username, $password);
99
        }
100
 
101
        public function getUserInfo($userPrincipalName, $cfg_ldap_base_dn) {
102
                $cfg_ldap_user_filter = "(&(objectClass=user)(objectCategory=person)(userPrincipalName=".ldap_escape($userPrincipalName, '', LDAP_ESCAPE_FILTER)."))";
103
 
104
                if (!($result = @ldap_search($this->conn,$cfg_ldap_base_dn, $cfg_ldap_user_filter))) throw new Exception(self::_L('Error in search query: %1', ldap_error($this->conn)));
105
                $data = ldap_get_entries($this->conn, $result);
106
                $ldap_userinfo = array();
107
 
108
                if ($data['count'] == 0) return false;
109
                $ldap_userinfo = $data[0];
110
 
111
                // empty($ldap_userinfo) can happen if the user did not log-in using their correct userPrincipalName (e.g. "username@domainname" instead of "username@domainname.local")
112
                return empty($ldap_userinfo) ? false : $ldap_userinfo;
113
        }
114
 
115
}