Completed
Pull Request — master (#2936)
by
unknown
04:53
created

includes/authentication/ldap-authorization.inc.php (14 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/*
3
 * This program is free software: you can redistribute it and/or modify
4
 * it under the terms of the GNU General Public License as published by
5
 * the Free Software Foundation, either version 3 of the License, or
6
 * (at your option) any later version.
7
 *
8
 * This program is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
11
 * GNU General Public License for more details.
12
 *
13
 * You should have received a copy of the GNU General Public License
14
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
 */
16
17
/**
18
 * libreNMS HTTP-Authentication and LDAP Authorization Library
19
 * @author Maximilian Wilhelm <[email protected]>
20
 * @copyright 2016 LibreNMS, Barbarossa
21
 * @license GPL
22
 * @package LibreNMS
23
 * @subpackage Authentication
24
 *
25
 * This Authentitation / Authorization module provides the ability to let
26
 * the webserver (e.g. Apache) do the user Authentication (using Kerberos
27
 * f.e.) and let libreNMS do the Authorization of the already known user.
28
 * Authorization and setting of libreNMS user level is done by LDAP group
29
 * names specified in the configuration file. The group configuration is
30
 * basicly copied from the existing ldap Authentication module.
31
 *
32
 * Most of the code is copied from the http-auth and ldap Authentication
33
 * modules already existing.
34
 *
35
 * To save lots of redundant queries to the LDAP server and speed up the
36
 * libreNMS WebUI, all information is cached within the PHP $_SESSION as
37
 * long as specified in $config['auth_ldap_cache_ttl'] (Default: 300s).
38
 */
39
40
41
if (! isset ($_SESSION['username'])) {
42
    $_SESSION['username'] = '';
43
}
44
45
/**
46
 * Set up connection to LDAP server
47
 */
48
$ds = @ldap_connect ($config['auth_ldap_server'], $config['auth_ldap_port']);
49
if (! $ds) {
50
    echo '<h2>Fatal error while connecting to LDAP server ' . $config['auth_ldap_server'] . ':' . $config['auth_ldap_port'] . ': ' . ldap_error($ds) . '</h2>';
51
    exit;
52
}
53
if ($config['auth_ldap_version']) {
54
    ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, $config['auth_ldap_version']);
55
}
56
57 View Code Duplication
if ($config['auth_ldap_starttls'] && ($config['auth_ldap_starttls'] == 'optional' || $config['auth_ldap_starttls'] == 'require')) {
58
    $tls = ldap_start_tls($ds);
59
    if ($config['auth_ldap_starttls'] == 'require' && $tls === false) {
60
        echo '<h2>Fatal error: LDAP TLS required but not successfully negotiated:' . ldap_error($ds) . '</h2>';
61
        exit;
62
    }
63
}
64
65
66
function authenticate ($username, $password) {
0 ignored issues
show
The function authenticate() has been defined more than once; this definition is ignored, only the first definition in html/includes/authentica...ctive_directory.inc.php (L18-60) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
67
    global $config;
68
69
    if (isset ($_SERVER['REMOTE_USER'])) {
70
        $_SESSION['username'] = mres ($_SERVER['REMOTE_USER']);
71
72
        if (user_exists ($_SESSION['username'])) {
73
            return 1;
74
        }
75
76
        $_SESSION['username'] = $config['http_auth_guest'];
77
        return 1;
78
    }
79
80
    return 0;
81
}
82
83
84
function reauthenticate ($sess_id='', $token='') {
0 ignored issues
show
The function reauthenticate() has been defined more than once; this definition is ignored, only the first definition in html/includes/authentica...ctive_directory.inc.php (L62-65) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
85
    // Not supported
86
    return 0;
87
}
88
89
90
function passwordscanchange ($username='') {
0 ignored issues
show
The function passwordscanchange() has been defined more than once; this definition is ignored, only the first definition in html/includes/authentica...ctive_directory.inc.php (L68-71) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
91
    // Not supported
92
    return 0;
93
}
94
95
96
function changepassword ($username, $newpassword) {
0 ignored issues
show
The function changepassword() has been defined more than once; this definition is ignored, only the first definition in html/includes/authentica...ctive_directory.inc.php (L74-77) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
97
    // Not supported
98
    return 0;
99
}
100
101
102
function auth_usermanagement () {
0 ignored issues
show
The function auth_usermanagement() has been defined more than once; this definition is ignored, only the first definition in html/includes/authentica...ctive_directory.inc.php (L80-83) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
103
    // Not supported
104
    return 0;
105
}
106
107
108
function adduser ($username, $password, $level, $email = '', $realname = '', $can_modify_passwd = 1, $description = '', $twofactor = 0) {
0 ignored issues
show
The function adduser() has been defined more than once; this definition is ignored, only the first definition in html/includes/authentica...ctive_directory.inc.php (L86-103) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
109
    // Not supported
110
    return false;
111
}
112
113
114
function user_exists ($username) {
0 ignored issues
show
The function user_exists() has been defined more than once; this definition is ignored, only the first definition in html/includes/authentica...ctive_directory.inc.php (L110-123) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
115
    global $config, $ds;
116
117
    if (auth_ldap_session_cache_get ('user_exists'))
118
        return 1;
119
120
    $filter  = '(' . $config['auth_ldap_prefix'] . $username . ')';
121
    $search  = ldap_search ($ds, trim ($config['auth_ldap_suffix'], ','), $filter);
122
    $entries = ldap_get_entries ($ds, $search);
123
    if ($entries['count']) {
124
        /*
125
	 * Cache positiv result as this will result in more queries which we
126
	 * want to speed up.
127
	 */
128
        auth_ldap_session_cache_set ('user_exists', 1);
129
        return 1;
130
    }
131
132
    /*
133
     * Don't cache that user doesn't exists as this might be a misconfiguration
134
     * on some end and the user will be happy if it "just works" after the user
135
     * has been added to LDAP.
136
     */
137
    return 0;
138
}
139
140
141
function get_userlevel ($username) {
0 ignored issues
show
The function get_userlevel() has been defined more than once; this definition is ignored, only the first definition in html/includes/authentica...ctive_directory.inc.php (L126-145) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
142
    global $config, $ds;
143
144
    $userlevel = auth_ldap_session_cache_get ('userlevel');
145
    if ($userlevel) {
146
        return $userlevel;
147
    } else {
148
        $userlevel = 0;
149
    }
150
151
    // Find all defined groups $username is in
152
    $filter  = '(&(|(cn=' . join (')(cn=', array_keys ($config['auth_ldap_groups'])) . '))(' . $config['auth_ldap_groupmemberattr'] .'=' . get_membername ($username) . '))';
153
    $search  = ldap_search ($ds, $config['auth_ldap_groupbase'], $filter);
154
    $entries = ldap_get_entries($ds, $search);
155
156
    // Loop the list and find the highest level
157 View Code Duplication
    foreach ($entries as $entry) {
158
        $groupname = $entry['cn'][0];
159
        if ($config['auth_ldap_groups'][$groupname]['level'] > $userlevel) {
160
            $userlevel = $config['auth_ldap_groups'][$groupname]['level'];
161
        }
162
    }
163
164
    auth_ldap_session_cache_set ('userlevel', $userlevel);
165
    return $userlevel;
166
}
167
168
169
170
function get_userid ($username) {
0 ignored issues
show
The function get_userid() has been defined more than once; this definition is ignored, only the first definition in html/includes/authentica...ctive_directory.inc.php (L148-161) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
171
    global $config, $ds;
172
173
    $user_id = auth_ldap_session_cache_get ('userid');
174
    if (isset ($user_id)) {
175
        return $user_id;
176
    } else {
177
        $user_id = -1;
178
    }
179
180
    $filter  = '(' . $config['auth_ldap_prefix'] . $username . ')';
181
    $search  = ldap_search ($ds, trim ($config['auth_ldap_suffix'], ','), $filter);
182
    $entries = ldap_get_entries ($ds, $search);
183
184
    if ($entries['count']) {
185
        $user_id = $entries[0]['uidnumber'][0];
186
    }
187
188
    auth_ldap_session_cache_set ('userid', $user_id);
189
    return $user_id;
190
}
191
192
193
function deluser ($username) {
0 ignored issues
show
The function deluser() has been defined more than once; this definition is ignored, only the first definition in html/includes/authentica...ctive_directory.inc.php (L164-171) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
194
    // Not supported
195
    return 0;
196
}
197
198
199 View Code Duplication
function get_userlist () {
0 ignored issues
show
The function get_userlist() has been defined more than once; this definition is ignored, only the first definition in html/includes/authentica...ctive_directory.inc.php (L174-217) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
200
    global $config, $ds;
201
    $userlist = array ();
202
203
    $filter = '(' . $config['auth_ldap_prefix'] . '*)';
204
205
    $search  = ldap_search ($ds, trim ($config['auth_ldap_suffix'], ','), $filter);
206
    $entries = ldap_get_entries ($ds, $search);
207
208
    if ($entries['count']) {
209
        foreach ($entries as $entry) {
210
            $username    = $entry['uid'][0];
211
            $realname    = $entry['cn'][0];
212
            $user_id     = $entry['uidnumber'][0];
213
            $email       = $entry[$config['auth_ldap_emailattr']][0];
214
            $ldap_groups = get_group_list ();
215
            foreach ($ldap_groups as $ldap_group) {
216
                $ldap_comparison = ldap_compare(
217
                    $ds,
218
                    $ldap_group,
219
                    $config['auth_ldap_groupmemberattr'],
220
                    get_membername($username)
221
                );
222
                if (! isset ($config['auth_ldap_group']) || $ldap_comparison === true) {
223
                    $userlist[] = array(
224
                                   'username' => $username,
225
                                   'realname' => $realname,
226
                                   'user_id'  => $user_id,
227
                                   'email'    => $email,
228
                                  );
229
                }
230
            }
231
        }
232
    }
233
234
    return $userlist;
235
}
236
237
238
function can_update_users () {
0 ignored issues
show
The function can_update_users() has been defined more than once; this definition is ignored, only the first definition in html/includes/authentica...ctive_directory.inc.php (L220-223) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
239
    // not supported
240
    return 0;
241
}
242
243
244
function get_user ($user_id) {
0 ignored issues
show
The function get_user() has been defined more than once; this definition is ignored, only the first definition in html/includes/authentica...ctive_directory.inc.php (L226-229) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
245
    // Not supported
246
    return 0;
247
}
248
249
250
function update_user ($user_id, $realname, $level, $can_modify_passwd, $email) {
0 ignored issues
show
The function update_user() has been defined more than once; this definition is ignored, only the first definition in html/includes/authentica...ctive_directory.inc.php (L232-234) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
251
    // Not supported
252
    return 0;
253
}
254
255
256 View Code Duplication
function get_membername ($username) {
257
    global $config, $ds;
258
    if ($config['auth_ldap_groupmembertype'] == 'fulldn') {
259
        $membername = $config['auth_ldap_prefix'] . $username . $config['auth_ldap_suffix'];
260
    }
261
    elseif ($config['auth_ldap_groupmembertype'] == 'puredn') {
262
        $filter  = '(' . $config['auth_ldap_attr']['uid'] . '=' . $username . ')';
263
        $search  = ldap_search($ds, $config['auth_ldap_groupbase'], $filter);
264
        $entries = ldap_get_entries($ds, $search);
265
        $membername = $entries[0]['dn'];
266
    }
267
    else {
268
        $membername = $username;
269
    }
270
271
    return $membername;
272
}
273
274
275
function auth_ldap_session_cache_get ($attr) {
276
    global $config;
277
278
    $ttl = 300;
279
    if ($config['auth_ldap_cache_ttl'])
280
        $ttl = $config['auth_ldap_cache_ttl'];
281
282
    // auth_ldap cache present in this session?
283
    if (! isset ($_SESSION['auth_ldap']))
284
        return Null;
285
286
    $cache = $_SESSION['auth_ldap'];
287
288
    // $attr present in cache?
289
    if (! isset ($cache[$attr]))
290
        return Null;
291
292
    // Value still valid?
293
    if (time () - $cache[$attr]['last_updated'] >= $ttl)
294
        return Null;
295
296
    $cache[$attr]['value'];
297
}
298
299
300
function auth_ldap_session_cache_set ($attr, $value) {
301
    $_SESSION['auth_ldap'][$attr]['value'] = $value;
302
    $_SESSION['auth_ldap'][$attr]['last_updated'] = time ();
303
}
304