forked from juho-jaakkola/elgg-ldap_auth
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstart.php
253 lines (206 loc) · 6.85 KB
/
start.php
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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
<?php
/**
* Elgg LDAP authentication
*
* @package ElggLDAPAuth
* @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2
* @author Misja Hoebe <[email protected]>
* @link http://community.elgg.org/profile/misja
*/
// Register the initialization function
elgg_register_event_handler('init', 'system', 'ldap_auth_init');
/**
* LDAP Authentication init
*/
function ldap_auth_init() {
// Register the authentication handler
register_pam_handler('ldap_auth_authenticate');
elgg_unregister_plugin_hook_handler('usersettings:save', 'user', '_elgg_set_user_password');
// Deregister default action for password changing
elgg_unregister_action('usersettings/save');
// Register own password changing action
elgg_register_action('usersettings/save', dirname(__FILE__) . "/actions/save.php");
}
/**
* Get an instance of the LdapServer class
*
* @return
*/
function ldap_auth_get_server() {
$settings = elgg_get_plugin_from_id('ldap_auth');
static $server;
if (!$server) {
try {
$server = new LdapServer($settings);
} catch (Exception $e) {
elgg_log($e->getMessage());
return false;
}
}
return $server;
}
/**
* Authenticate user against the credential
*
* @param array $credentials
* @return boolean
*/
function ldap_auth_authenticate($credentials) {
$settings = elgg_get_plugin_from_id('ldap_auth');
$server = ldap_auth_get_server();
if (!$server) {
// Unable to connect to LDAP server
register_error(elgg_echo('ldap_auth:connection_error'));
return false;
}
$settings = elgg_get_plugin_from_id('ldap_auth');
$username = elgg_extract('username', $credentials);
$password = elgg_extract('password', $credentials);
$filter = "({$settings->filter_attr}={$username})";
if (!$server->bind()) {
register_error(elgg_echo('ldap_auth:connection_error'));
return false;
}
$result = $server->search($filter);
if (empty($result)) {
// User was not found
return false;
}
// Bind using user's distinguished name and password
$success = $server->bind($result['dn'], $password);
if (!$success) {
// dn/password combination doesn't exist
return false;
}
// Check if the user is a member of the group, in case both parameters are filled
$result2 = $server->isMember($result['dn']);
if (!$result2) {
elgg_log("User found in directory and its bind completed ok, but is not a member of the required group","NOTICE");
register_error(elgg_echo('ldap_auth:not_in_group'));
return false;
}
$user = get_user_by_username($username);
if ($user) {
return login($user);
}
if ($settings->create_user !== 'off') {
return ldap_auth_create_user($username, $result);
}
register_error(elgg_echo("ldap_auth:no_account"));
return false;
}
/**
* Create a new user from the data provided by LDAP
*
* @param string $username
* @param string $password
* @param array $data Data fetched from LDAP
*/
function ldap_auth_create_user($username, $data) {
// Check that we have the values. register_user() will take
// care of more detailed validation.
$firstname = elgg_extract('firstname', $data);
$lastname = elgg_extract('lastname', $data);
$email = elgg_extract('mail', $data);
$password = substr(str_shuffle(str_repeat('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', mt_rand(1,10))),1,20);
// Combine firstname and lastname
$name = implode(' ', array($firstname, $lastname));
try {
$guid = register_user($username, $password, $name, $email);
} catch (Exception $e) {
register_error($e->getMessage());
return false;
}
if (!$guid) {
register_error(elgg_echo('ldap_auth:no_register'));
elgg_log("Failed to create an account for LDAP user $username");
return false;
}
$user = get_entity($guid);
// Allow plugins to respond to the registration
$params = array(
'user' => $user,
'ldap_entry' => $data,
);
if (!elgg_trigger_plugin_hook('register', 'user', $params, true)) {
// For some reason one of the plugins returned false.
// This most likely means that something went wrong
// and we will have to remove the user.
$user->delete();
register_error(elgg_echo('registerbad'));
return false;
}
// Validate the user
elgg_set_user_validation_status($guid, true, 'LDAP plugin based validation');
return true;
}
/**
* Change LDAP user's password
*
* @param string $user user name
* @param string $oldPassword old password
* @param string $newPassword new password
* @param string $newPasswordCnf new password
* @return bool status of change
*/
function ldap_auth_change_password( $user, $oldPassword, $newPassword, $newPasswordCnf ) {
$settings = elgg_get_plugin_from_id('ldap_auth');
$server = ldap_auth_get_server();
ldap_connect($server);
$con = ldap_connect($server->hostname, $server->port);
ldap_set_option($con, LDAP_OPT_PROTOCOL_VERSION, 3);
// bind anon and find user by uid
$user_search = ldap_search($con, $server->basedn, "(uid=$user)");
$user_get = ldap_get_entries($con, $user_search);
$user_entry = ldap_first_entry($con, $user_search);
$user_dn = ldap_get_dn($con, $user_entry);
/* Start the testing */
if (ldap_bind($con, $user_dn, $oldPassword) === false) {
register_error(elgg_echo('ldap_auth:password:change:binderror'));
return false;
}
if ($newPassword != $newPasswordCnf ) {
register_error(elgg_echo('ldap_auth:password:change:newnotmatch'));
return false;
}
if ($newPassword == $oldPassword ) {
register_error(elgg_echo('ldap_auth:password:change:samepass'));
return false;
}
if (strlen($newPassword) < 8 ) {
register_error(elgg_echo('ldap_auth:password:change:passlenght'));
return false;
}
if (!preg_match("/[0-9]/",$newPassword)) {
register_error(elgg_echo('ldap_auth:password:change:nonumber'));
return false;
}
if (!preg_match("/[a-zA-Z]/",$newPassword)) {
register_error(elgg_echo('ldap_auth:password:change:noletter'));
return false;
}
if (!preg_match("/[A-Z]/",$newPassword)) {
register_error(elgg_echo('ldap_auth:password:change:noupper'));
return false;
}
if (!preg_match("/[a-z]/",$newPassword)) {
register_error(elgg_echo('ldap_auth:password:change:nolower'));
return false;
}
if (!$user_get) {
register_error(elgg_echo('ldap_auth:password:change:conerror'));
return false;
}
/* And Finally, Change the password */
$entry = array();
$entry["userPassword"] = "{SHA}" . base64_encode( pack( "H*", sha1( $newPassword ) ) );
if (ldap_modify($con,$user_dn,$entry) === false){
$error = ldap_error($con);
$errno = ldap_errno($con);
register_error(elgg_echo('ldap_auth:password:change:error'));
return false;
} else {
system_message(elgg_echo('ldap_auth:password:change:success'));
return true;
}
}