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
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
|
<?php
/**
* $Header$
*
* @package users
*/
/**
* required setup
*/
if (file_exists(UTIL_PKG_INCLUDE_PATH."pear/Auth/Auth.php")) {
require_once (UTIL_PKG_INCLUDE_PATH."pear/Auth/Auth.php");
} else {
// THIS may need changing if a different PEAR installation is used
include_once("Auth/Auth.php");
}
/**
* Class that manages the PEAR:ldap autentication method
*
* @package users
* @subpackage auth
*/
class LDAPAuth extends BaseAuth {
function __construct() {
parent::__construct('ldap');
}
function validate($user,$pass,$challenge,$response) {
parent::validate($user,$pass,$challenge,$response);
global $gBitDb;
if ( empty($user) or empty($pass) ) {
return USER_NOT_FOUND;
}
$this->mInfo["real_name"] = ''; // This needs fixing in the base code - real_name will only exist if a user has been identiied
// Use V3, which requires UTF-8:
$this->mConfig['version'] = 3;
$user_utf8 = utf8_encode( $user );
if ( $this->mConfig['reqcert'] ) {
// Skip the SSL certificate check:
// (This assumes PHP is using the OpenLDAP client library.)
putenv('LDAPTLS_REQCERT=never');
}
if ( $this->mConfig['activedirectory'] ) {
$this->mConfig['attributes'] = (array) null;
$this->mConfig['userfilter'] = '(objectClass='.$this->mConfig['useroc'].')';
$this->mConfig['groupfilter'] = '(objectClass='.$this->mConfig['groupoc'].')';
$this->mConfig['groupscope'] = $this->mConfig['userscope'];
} else {
// Using bitweaver groups with LDAP still needs completing so disable for now
unset($this->mConfig['group']);
}
$a = new Auth('LDAP', $this->mConfig, "", false);
$a->_loadStorage(); // set up connection to ldap via user details
// First, try by username. If that fails, try by email address.
$success = $a->storage->fetchData($user_utf8, $pass, false);
if ($success == false) {
// The user wasn't found. Try again by email address:
$this->mConfig['userattrsto'] = $this->mConfig['userattr']; // Keep this for later
$this->mConfig['userattr'] = $this->mConfig['email']; // Tell PEAR::Auth() to look at the 'mail' attribute
// this needs testing better, should be no need to create second instance of Auth!
$a = new Auth('LDAP', $this->mConfig, "", false);
$a->_loadStorage(); // set up connection to ldap via user details
$success = $a->storage->fetchData($user_utf8, $pass, false);
if ($success == false) {
$this->mErrors['login'] = isset($a->storage->options['status']) ? $a->storage->options['status'] : 'Not authenticated';
return PASSWORD_INCORRECT;
}
}
// At this point, there was a successful ldap_bind() using the
// user's Distinguished Name (DN) and password for login.
// The call to ldap_get_attributes() has been saved into $a->getAuthData('attributes')
if ( $this->mConfig['activedirectory'] ) {
// Active Directory does some things differently - mainly in the returns
$attributes = $a->getAuthData();
// Warning: ldap_get_attributes() uses case-sensitive array keys
$this->mInfo["login"] = $attributes[ $this->mConfig['userattr'] ];
$this->mInfo["email"] = $attributes[ $this->mConfig['email'] ];
$this->mInfo["real_name"] = empty($attributes[$this->mConfig['name']]) ? $this->mInfo["login"] : $attributes[$this->mConfig['name']];
}
else {
$attributes = $a->getAuthData('attributes');
// Warning: ldap_get_attributes() uses case-sensitive array keys
$this->mInfo["login"] = $attributes[ $this->mConfig['userattr'] ][0];
$this->mInfo["email"] = $attributes[ $this->mConfig['email'] ][0];
$this->mInfo["real_name"] = empty($attributes[$this->mConfig['name']][0]) ? $this->mInfo["login"] : $attributes[$this->mConfig['name']][0];
}
// Note, the new (or updated) SQL user will be created by the calling BitUser class.
return USER_VALID; // Success!
}
function isSupported() {
$ret = true;
if (!class_exists("Auth")) {
$this->mErrors['support']=tra("LDAP Authentication is not supported as PEAR Package Auth is not availible.");
$ret = false;
}
if (!function_exists('ldap_connect')) {
$this->mErrors['support']=tra("LDAP Authentication is not supported as PHP LDAP Extention not loaded.");
$ret = false;
}
return $ret;
}
// create a new user in the Auth directory
function createUser(&$userattr) {
global $gBitDb;
// set additional attributes here
if (empty($userattr["email"])) {
$userattr["email"] = $gBitDb->getOne("select `email` from `".BIT_DB_PREFIX."users_users` where `login`=?", array($userattr["login"]));
}
// set the Auth options
$a = new Auth("LDAP", $this->mConfig);
// check if the login correct
if ($a->addUser($userattr["login"], $userattr["password"], $userattr) === true) {
return true;
} else {
// otherwise use the error status given back
$this->mErrors['create'] = $a->getStatus();
return false;
}
}
function canManageAuth() {
return true;
}
function getSettings() {
global $gBitUser;
$listHash = array();
// Roles are not inteneded to match with ldap groups
// This area needs a closer look if it needs to be used
$groups = array();
$groups = $gBitUser->getAllGroups($listHash);
$groupsD = array();
foreach ($groups as $g) {
$groupsD[$g['group_id']]= "{$g['group_name']} ( {$g['group_desc']} )";
}
$groups = $groupsD;
return array(
'users_ldap_url' => array(
'label' => "LDAP Connection URL",
'type' => "text",
'note' => "You can specify an LDAP URL, like ldap://localhost/ or ldaps://some-server/.",
'default' => '',
),
'users_ldap_host' => array(
'label' => "LDAP Host",
'type' => "text",
'note' => "Instead of a URL, you can specify a hostname and port explicitly. Give either a URL, or else a hostname/port (but not both).",
'default' => 'localhost',
),
'users_ldap_port' => array(
'label' => "LDAP Port",
'type' => "text",
'note' => "",
'default' => '389',
),
'users_ldap_start_tls' => array(
'label' => "Use Start-TLS?",
'type' => "checkbox",
'note' => "Please note there is a difference between ldaps:// and Start-TLS for ldap. Start-TLS uses port 389, while ldaps:// uses port 636. Both encrypted LDAP (with Start-TLS) and unencrypted LDAP can run on port 389 concurrently.",
'default' => 'y',
),
'users_ldap_reqcert' => array(
'label' => "Skip the SSL Cert validation?",
'type' => "checkbox",
'note' => "If Start-TLS is checked, then your LDAP server needs a trusted SSL cert -- unless you check this option, in which case you can use a self-signed (untrusted) cert.",
'default' => 'y',
),
'users_ldap_referrals' => array(
'label' => "Use Referrals?",
'type' => "checkbox",
'note' => "This should probably be 'yes'. (Only applies to LDAP V3 servers.)",
'default' => 'y',
),
'users_ldap_basedn' => array(
'label' => "LDAP Base DN",
'type' => "text",
'note' => "",
'default' => '',
),
'users_ldap_userdn' => array(
'label' => "LDAP User DN",
'type' => "text",
'note' => "",
'default' => '',
),
'users_ldap_userattr' => array(
'label' => "LDAP User Attribute",
'type' => "text",
'note' => "The LDAP Attribute to use for the user's login in Bitweaver. (This is the first attribute searched when the user logs in.)",
'default' => 'uid',
),
'users_ldap_email' => array(
'label' => "LDAP User E-Mail Address",
'type' => "text",
'note' => "The LDAP Attribute to use for the user's email address in Bitweaver. (This is the second attribute searched when the user logs in.)",
'default' => 'mail',
),
'users_ldap_name' => array(
'label' => "LDAP User Display Name",
'type' => "text",
'note' => "The LDAP Attribute to use for the user's Full Name in Bitweaver.",
'default' => 'displayName',
),
'users_ldap_useroc' => array(
'label' => "LDAP User OC",
'type' => "text",
'note' => "",
'default' => '(objectClass=inetOrgPerson)',
),
'users_ldap_groupdn' => array(
'label' => "LDAP Group DN",
'type' => "text",
'note' => "",
'default' => '',
),
'users_ldap_groupattr' => array(
'label' => "LDAP Group Atribute",
'type' => "text",
'note' => "",
'default' => 'cn',
),
'users_ldap_groupoc' => array(
'label' => "LDAP Group OC",
'type' => "text",
'note' => "",
'default' => '(objectClass=groupOfUniqueNames)',
),
'users_ldap_memberattr' => array(
'label' => "LDAP Member Attribute",
'type' => "text",
'note' => "",
'default' => 'uniqueMember',
),
'users_ldap_memberisdn' => array(
'label' => "LDAP Member Is DN",
'type' => "checkbox",
'note' => "",
'default' => 'n',
),
'users_ldap_binddn' => array(
'label' => "LDAP Bind DN",
'type' => "text",
'note' => "This DN will be used to search the LDAP directory for users. If left blank, 'anonymous bind' is used.",
'default' => '',
),
'users_ldap_bindpw' => array(
'label' => "LDAP Bind Pwd",
'type' => "password",
'note' => "",
'default' => '',
),
'users_ldap_userscope' => array(
'label' => "LDAP Scope to use when searching for users",
'type' => "option",
'note' => "",
'default' => 'sub',
'options' => array(
'sub' => "Sub",
'one' => "One",
'base' => "Base",
),
),
'users_ldap_group' => array(
'label' => "LDAP Group Requirement",
'type' => "text",
'note' => "If this is specified, then the LDAP user must also be a member of this LDAP group to connect.",
'default' => ''
),
'users_ldap_activedirectory' => array(
'label' => "Active Directory?",
'type' => "checkbox",
'note' => "",
'default' => 'n'
),
);
}
}
?>
|