Issues (1098)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

src/dbo/accounts.php (2 issues)

mismatching argument types.

Documentation Minor

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
//------------------------------------------------------------------------------
4
//
5
//  eTraxis - Records tracking web-based system
6
//  Copyright (C) 2005-2013  Artem Rodygin
7
//
8
//  This program is free software: you can redistribute it and/or modify
9
//  it under the terms of the GNU General Public License as published by
10
//  the Free Software Foundation, either version 3 of the License, or
11
//  (at your option) any later version.
12
//
13
//  This program is distributed in the hope that it will be useful,
14
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
//  GNU General Public License for more details.
17
//
18
//  You should have received a copy of the GNU General Public License
19
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
//
21
//------------------------------------------------------------------------------
22
23
/**
24
 * Accounts
25
 *
26
 * This module provides API to work with eTraxis accounts.
27
 * See also {@link https://github.com/etraxis/etraxis-obsolete/wiki/tbl_accounts tbl_accounts} database table.
28
 *
29
 * @package DBO
30
 * @subpackage Accounts
31
 */
32
33
/**#@+
34
 * Dependency.
35
 */
36
require_once('../engine/engine.php');
37
require_once('../dbo/filters.php');
38
require_once('../dbo/views.php');
39
/**#@-*/
40
41
//------------------------------------------------------------------------------
42
//  Definitions.
43
//------------------------------------------------------------------------------
44
45
/**
46
 * Local accounts suffix.
47
 */
48
define('ACCOUNT_SUFFIX', '@eTraxis');
49
50
/**#@+
51
 * Data restriction.
52
 */
53
define('MAX_ACCOUNT_USERNAME',    104);
54
define('MAX_ACCOUNT_PASSWORD',    104);
55
define('MAX_ACCOUNT_FULLNAME',    64);
56
define('MAX_ACCOUNT_EMAIL',       50);
57
define('MAX_ACCOUNT_DESCRIPTION', 100);
58
/**#@-*/
59
60
/**
61
 * Default notifications filter and flags.
62
 */
63
define('DEFAULT_NOTIFY_FLAG', 0x0000FFFF);
64
65
//------------------------------------------------------------------------------
66
//  Functions.
67
//------------------------------------------------------------------------------
68
69
/**
70
 * Checks whether account with specified locking info is still locked.
71
 *
72
 * @param int $locks_count Current value of 'locks_count' DBO field.
73
 * @param int $lock_time Current value of 'lock_time' DBO field.
74
 * @return bool TRUE if account is locked, FALSE otherwise.
75
 */
76
function is_account_locked ($locks_count, $lock_time)
77
{
78
    debug_write_log(DEBUG_TRACE, '[is_account_locked]');
79
    debug_write_log(DEBUG_DUMP,  '[is_account_locked] $locks_count = ' . $locks_count);
80
    debug_write_log(DEBUG_DUMP,  '[is_account_locked] $lock_time   = ' . $lock_time);
81
82
    return ($locks_count >= LOCKS_COUNT) && ($lock_time + LOCKS_TIMEOUT * 60 >= time());
83
}
84
85
/**
86
 * Increase number of failed attempts to log in ('locks_count' DBO field) for specified account.
87
 * Account is locked when maximum allowed attempts to login is reached ({@link LOCKS_COUNT}).
88
 *
89
 * @param int $id Account ID.
90
 * @return int Always {@link NO_ERROR}.
91
 */
92
function account_lock ($id)
93
{
94
    debug_write_log(DEBUG_TRACE, '[account_lock]');
95
    debug_write_log(DEBUG_DUMP,  '[account_lock] $id = ' . $id);
96
97
    dal_query('accounts/lock.sql', $id, time());
98
99
    return NO_ERROR;
100
}
101
102
/**
103
 * Clears number of failed attempts to log in ('locks_count' DBO field) for specified account.
104
 *
105
 * @param int $id Account ID.
106
 * @return int Always {@link NO_ERROR}.
107
 */
108
function account_unlock ($id)
109
{
110
    debug_write_log(DEBUG_TRACE, '[account_unlock]');
111
    debug_write_log(DEBUG_DUMP,  '[account_unlock] $id = ' . $id);
112
113
    dal_query('accounts/unlock.sql', $id);
114
115
    return NO_ERROR;
116
}
117
118
/**
119
 * Disables specified account.
120
 *
121
 * @param int $id Account ID.
122
 * @return int Always {@link NO_ERROR}.
123
 */
124 View Code Duplication
function account_disable ($id)
125
{
126
    debug_write_log(DEBUG_TRACE, '[account_disable]');
127
    debug_write_log(DEBUG_DUMP,  '[account_disable] $id = ' . $id);
128
129
    dal_query('accounts/disable.sql', $id, bool2sql(TRUE));
130
131
    return NO_ERROR;
132
}
133
134
/**
135
 * Enables specified account.
136
 *
137
 * @param int $id Account ID.
138
 * @return int Always {@link NO_ERROR}.
139
 */
140 View Code Duplication
function account_enable ($id)
141
{
142
    debug_write_log(DEBUG_TRACE, '[account_enable]');
143
    debug_write_log(DEBUG_DUMP,  '[account_enable] $id = ' . $id);
144
145
    dal_query('accounts/disable.sql', $id, bool2sql(FALSE));
146
147
    return NO_ERROR;
148
}
149
150
/**
151
 * Looks for Account ID and token, which are stored in client cookies,
152
 * and checks that token, stored in database for the same user, is equal.
153
 *
154
 * See also {@link account_set_token}.
155
 *
156
 * @return int Account ID if valid equal token is found in database, 0 otherwise.
157
 */
158
function account_get_token ()
159
{
160
    debug_write_log(DEBUG_TRACE, '[account_get_token]');
161
162
    $id    = try_cookie(COOKIE_AUTH_USERID, 0);
163
    $token = try_cookie(COOKIE_AUTH_TOKEN,  0);
164
165
    $id = ustr2int($id);
166
167
    $rs = dal_query('accounts/gettoken.sql', $id, $token, time());
168
169
    return ($rs->rows == 0 ? 0 : $id);
170
}
171
172
/**
173
 * Generates a token for specified Account ID, and saves it in the database and client cookies.
174
 *
175
 * <i>Token</i> is a special MD5 hash, specific to Account ID, client IP address, and time of generation.
176
 * Tokens are stored in both database (auth_token, token_expire) and client cookies ({@link COOKIE_AUTH_USERID},
177
 * {@link COOKIE_AUTH_TOKEN}), and has an expiration specified in {@link SESSION_EXPIRE}.
178
 * When user tries to log in, eTraxis checks for token of this user in database - if it equals to
179
 * token stored in client cookies and is not expired yet, than user is pretended as already logged in,
180
 * and eTraxis does not request for user's credentials.
181
 *
182
 * @param int $id Account ID.
183
 * @return int Always {@link NO_ERROR}.
184
 */
185
function account_set_token ($id)
186
{
187
    debug_write_log(DEBUG_TRACE, '[account_set_token]');
188
    debug_write_log(DEBUG_DUMP,  '[account_set_token] $id = ' . $id);
189
190
    session_regenerate_id();
191
192
    $token = md5(WEBROOT . $id . $_SERVER['SERVER_ADDR'] . $_SERVER['SERVER_PORT'] . rand());
193
194
    save_cookie(COOKIE_AUTH_USERID, $id);
195
    save_cookie(COOKIE_AUTH_TOKEN,  $token);
196
197
    dal_query('accounts/settoken.sql', $id, $token, time() + SESSION_EXPIRE * 60);
198
199
    return NO_ERROR;
200
}
201
202
/**
203
 * Finds in database and returns the information about specified Account ID.
204
 *
205
 * @param int $id Account ID.
206
 * @return array Array with data if account is found in database, FALSE otherwise.
207
 */
208
function account_find ($id)
209
{
210
    debug_write_log(DEBUG_TRACE, '[account_find]');
211
    debug_write_log(DEBUG_DUMP,  '[account_find] $id = ' . $id);
212
213
    $rs = dal_query('accounts/fndid.sql', $id);
214
215
    return ($rs->rows == 0 ? FALSE : $rs->fetch());
216
}
217
218
/**
219
 * Finds in database and returns the information about account with specified user name.
220
 * To distinguish eTraxis accounts from LDAP ones, user name must be appended with
221
 * {@link ACCOUNT_SUFFIX} to search among eTraxis accounts (LDAP accounts otherwise).
222
 *
223
 * @param string $username User name of account.
224
 * @return array Array with data if account is found in database, FALSE otherwise.
225
 */
226
function account_find_username ($username)
227
{
228
    debug_write_log(DEBUG_TRACE, '[account_find_username]');
229
    debug_write_log(DEBUG_DUMP,  '[account_find_username] $username = ' . $username);
230
231
    $rs = dal_query('accounts/fndk.sql', ustrtolower($username));
232
233
    return ($rs->rows == 0 ? FALSE : $rs->fetch());
234
}
235
236
/**
237
 * Removes {@link ACCOUNT_SUFFIX} from specified user name if it presents and LDAP support is enabled.
238
 *
239
 * @param string $username User name.
240
 * @param bool $ldap_enabled Whether LDAP support is enabled (current value of {@link LDAP_ENABLED} by default).
241
 * @return string Clear user name.
242
 */
243
function account_get_username ($username, $ldap_enabled = LDAP_ENABLED)
244
{
245
    debug_write_log(DEBUG_TRACE, '[account_get_username]');
246
    debug_write_log(DEBUG_DUMP,  '[account_get_username] $username     = ' . $username);
247
    debug_write_log(DEBUG_DUMP,  '[account_get_username] $ldap_enabled = ' . $ldap_enabled);
248
249
    return ($ldap_enabled ? $username : ustr_replace(ACCOUNT_SUFFIX, NULL, $username));
250
}
251
252
/**
253
 * Returns {@link CRecordset DAL recordset} which contains all existing accounts and sorted in
254
 * accordance with current sort mode.
255
 *
256
 * @param int &$sort Sort mode (used as output only). The function retrieves current sort mode from
257
 * client cookie ({@link COOKIE_ACCOUNTS_SORT}) and updates it, if it's out of valid range.
258
 * @param int &$page Number of current page tab (used as output only). The function retrieves current
259
 * page from client cookie ({@link COOKIE_ACCOUNTS_PAGE}) and updates it, if it's out of valid range.
260
 * @return CRecordset Recordset with list of accounts.
261
 */
262
function accounts_list (&$sort, &$page)
263
{
264
    debug_write_log(DEBUG_TRACE, '[accounts_list]');
265
266
    $sort_modes = array
267
    (
268
        1  => 'username asc',
269
        2  => 'fullname asc, username asc',
270
        3  => 'email asc, username asc',
271
        4  => 'is_admin asc, username asc',
272
        5  => 'description asc, username asc',
273
        6  => 'username desc',
274
        7  => 'fullname desc, username desc',
275
        8  => 'email desc, username desc',
276
        9  => 'is_admin desc, username desc',
277
        10 => 'description desc, username desc',
278
    );
279
280
    $sort = try_request('sort', try_cookie(COOKIE_ACCOUNTS_SORT));
281
    $sort = ustr2int($sort, 1, count($sort_modes));
282
283
    $page = try_request('page', try_cookie(COOKIE_ACCOUNTS_PAGE));
284
    $page = ustr2int($page, 1, MAXINT);
285
286
    save_cookie(COOKIE_ACCOUNTS_SORT, $sort);
287
    save_cookie(COOKIE_ACCOUNTS_PAGE, $page);
288
289
    return dal_query('accounts/list.sql', $sort_modes[$sort]);
290
}
291
292
/**
293
 * Validates account information before creation or modification.
294
 *
295
 * @param string $username User name.
296
 * @param string $fullname Full name.
297
 * @param string $email Email address.
298
 * @param string $passwd1 First password entry.
299
 * @param string $passwd2 Second password entry.
300
 * @return int Error code:
301
 * <ul>
302
 * <li>{@link NO_ERROR} - data are valid</li>
303
 * <li>{@link ERROR_INCOMPLETE_FORM} - at least one of required field is empty</li>
304
 * <li>{@link ERROR_INVALID_USERNAME} - user name contains invalid characters</li>
305
 * <li>{@link ERROR_INVALID_EMAIL} - email address contains invalid characters</li>
306
 * <li>{@link ERROR_PASSWORDS_DO_NOT_MATCH} - entered password entries are not equal</li>
307
 * <li>{@link ERROR_PASSWORD_TOO_SHORT} - entered password is too short (see {@link MIN_PASSWORD_LENGTH})</li>
308
 * </ul>
309
 */
310
function account_validate ($username, $fullname, $email, $passwd1, $passwd2)
311
{
312
    debug_write_log(DEBUG_TRACE, '[account_validate]');
313
    debug_write_log(DEBUG_DUMP,  '[account_validate] $username = ' . $username);
314
    debug_write_log(DEBUG_DUMP,  '[account_validate] $fullname = ' . $fullname);
315
    debug_write_log(DEBUG_DUMP,  '[account_validate] $email    = ' . $email);
316
317
    if (ustrlen($username) == 0 ||
318
        ustrlen($fullname) == 0 ||
319
        ustrlen($email)    == 0 ||
320
        ustrlen($passwd1)  == 0 ||
321
        ustrlen($passwd2)  == 0)
322
    {
323
        debug_write_log(DEBUG_NOTICE, '[account_validate] At least one required field is empty.');
324
        return ERROR_INCOMPLETE_FORM;
325
    }
326
327
    if (!is_username($username))
328
    {
329
        debug_write_log(DEBUG_NOTICE, '[account_validate] Invalid username.');
330
        return ERROR_INVALID_USERNAME;
331
    }
332
333
    if (!is_email($email))
334
    {
335
        debug_write_log(DEBUG_NOTICE, '[account_validate] Invalid email.');
336
        return ERROR_INVALID_EMAIL;
337
    }
338
339
    if ($passwd1 != $passwd2)
340
    {
341
        debug_write_log(DEBUG_NOTICE, '[account_validate] Passwords do not match.');
342
        return ERROR_PASSWORDS_DO_NOT_MATCH;
343
    }
344
345
    if (ustrlen($passwd1) < MIN_PASSWORD_LENGTH)
346
    {
347
        debug_write_log(DEBUG_NOTICE, '[account_validate] Password is too short.');
348
        return ERROR_PASSWORD_TOO_SHORT;
349
    }
350
351
    return NO_ERROR;
352
}
353
354
/**
355
 * Creates new account.
356
 *
357
 * @param string $username User name.
358
 * @param string $fullname Full name.
359
 * @param string $email Email address.
360
 * @param string $passwd Password.
361
 * @param string $description Optional description.
362
 * @param bool $is_admin Whether new account will have administration privileges (see 'is_admin' DBO field).
363
 * @param bool $is_disabled Whether new account should be created in disabled state (see 'is_disabled' DBO field).
364
 * @param int $locale UI language (see 'locale' DBO field).
365
 * @param bool $is_ldapuser Whether new account is LDAP one (FALSE by default, see 'is_ldapuser' DBO field).
366
 * @return int Error code:
367
 * <ul>
368
 * <li>{@link NO_ERROR} - account is successfully created</li>
369
 * <li>{@link ERROR_ALREADY_EXISTS} - account with specified user name already exists</li>
370
 * <li>{@link ERROR_NOT_FOUND} - failure on attempt to create account</li>
371
 * </ul>
372
 */
373
function account_create ($username, $fullname, $email, $passwd, $description, $is_admin, $is_disabled, $locale, $is_ldapuser = FALSE)
374
{
375
    debug_write_log(DEBUG_TRACE, '[account_create]');
376
    debug_write_log(DEBUG_DUMP,  '[account_create] $username    = ' . $username);
377
    debug_write_log(DEBUG_DUMP,  '[account_create] $fullname    = ' . $fullname);
378
    debug_write_log(DEBUG_DUMP,  '[account_create] $email       = ' . $email);
379
    debug_write_log(DEBUG_DUMP,  '[account_create] $description = ' . $description);
380
    debug_write_log(DEBUG_DUMP,  '[account_create] $is_admin    = ' . $is_admin);
381
    debug_write_log(DEBUG_DUMP,  '[account_create] $is_disabled = ' . $is_disabled);
382
    debug_write_log(DEBUG_DUMP,  '[account_create] $locale      = ' . $locale);
383
    debug_write_log(DEBUG_DUMP,  '[account_create] $is_ldapuser = ' . $is_ldapuser);
384
385
    // Check that there is no account with the same user name.
386
    $rs = dal_query('accounts/fndk.sql', ustrtolower($username . ($is_ldapuser ? NULL : ACCOUNT_SUFFIX)));
387
388
    if ($rs->rows != 0)
389
    {
390
        debug_write_log(DEBUG_NOTICE, '[account_create] Account already exists.');
391
        return ERROR_ALREADY_EXISTS;
392
    }
393
394
    // Create an account.
395
    dal_query('accounts/create.sql',
396
              $username . ($is_ldapuser ? NULL : ACCOUNT_SUFFIX),
397
              $fullname,
398
              $email,
399
              base64_encode(sha1($passwd, TRUE)),
400
              ustrlen($description) == 0 ? NULL : $description,
401
              bool2sql($is_admin),
402
              bool2sql($is_disabled),
403
              bool2sql($is_ldapuser),
404
              $locale,
405
              HTML_TEXTBOX_DEFAULT_HEIGHT,
406
              DEFAULT_PAGE_ROWS,
407
              DEFAULT_PAGE_BKMS,
408
              THEME_DEFAULT);
409
410
    // Find newly created account.
411
    $rs = dal_query('accounts/fndk.sql', ustrtolower($username . ($is_ldapuser ? NULL : ACCOUNT_SUFFIX)));
412
413
    if ($rs->rows == 0)
414
    {
415
        debug_write_log(DEBUG_WARNING, '[account_create] Created account not found.');
416
        return ERROR_NOT_FOUND;
417
    }
418
419
    // Get an ID of the created account.
420
    $account_id = $rs->fetch('account_id');
421
422
    // Create default view for new account, which will contain both default filters.
423
    view_create($account_id, get_html_resource(RES_MY_RECORDS_ID, $locale));
424
425
    // Find newly created default view.
426
    $rs = dal_query('views/fndk.sql', $account_id, ustrtolower(get_html_resource(RES_MY_RECORDS_ID, $locale)));
427
428
    if ($rs->rows == 0)
429
    {
430
        debug_write_log(DEBUG_NOTICE, '[account_create] Created view not found.');
431
        $view_id = NULL;
432
    }
433
    else
434
    {
435
        $view_id = $rs->fetch('view_id');
436
        dal_query('accounts/setview.sql', $account_id, $view_id);
437
    }
438
439
    // Create 1st default filter for new account, which will show all records assigned to this account.
440
    dal_query('filters/create.sql',
441
              $account_id,
442
              get_html_resource(RES_ALL_ASSIGNED_TO_ME_ID, $locale),
443
              FILTER_TYPE_ALL_PROJECTS,
444
              FILTER_FLAG_ASSIGNED_TO,
445
              NULL);
446
447
    // Find 1st newly created default filter.
448
    $rs = dal_query('filters/fndk.sql',
449
                    $account_id,
450
                    ustrtolower(get_html_resource(RES_ALL_ASSIGNED_TO_ME_ID, $locale)));
451
452 View Code Duplication
    if ($rs->rows == 0)
453
    {
454
        debug_write_log(DEBUG_WARNING, '[account_create] Created filter #1 not found.');
455
    }
456
    else
457
    {
458
        $filter_id = $rs->fetch('filter_id');
459
460
        // Complete filter settings and active the filter.
461
        dal_query('filters/facreate.sql', $filter_id, FILTER_FLAG_ASSIGNED_TO, $account_id);
462
        dal_query('filters/set.sql', $filter_id, $account_id);
463
464
        // Add filter into default view.
465
        if (!is_null($view_id))
466
        {
467
            dal_query('views/fcreate.sql', $view_id, $filter_id);
468
        }
469
    }
470
471
    // Create 2nd default filter for new account, which will show all opened records created by this account.
472
    dal_query('filters/create.sql',
473
              $account_id,
474
              get_html_resource(RES_ALL_CREATED_BY_ME_ID, $locale),
475
              FILTER_TYPE_ALL_PROJECTS,
476
              FILTER_FLAG_CREATED_BY | FILTER_FLAG_UNCLOSED,
477
              NULL);
478
479
    // Find 2nd newly created default filter.
480
    $rs = dal_query('filters/fndk.sql',
481
                    $account_id,
482
                    ustrtolower(get_html_resource(RES_ALL_CREATED_BY_ME_ID, $locale)));
483
484 View Code Duplication
    if ($rs->rows == 0)
485
    {
486
        debug_write_log(DEBUG_WARNING, '[account_create] Created filter #2 not found.');
487
    }
488
    else
489
    {
490
        $filter_id = $rs->fetch('filter_id');
491
492
        // Complete filter settings and active the filter.
493
        dal_query('filters/facreate.sql', $filter_id, FILTER_FLAG_CREATED_BY, $account_id);
494
        dal_query('filters/set.sql', $filter_id, $account_id);
495
496
        // Add filter into default view.
497
        if (!is_null($view_id))
498
        {
499
            dal_query('views/fcreate.sql', $view_id, $filter_id);
500
        }
501
    }
502
503
    return NO_ERROR;
504
}
505
506
/**
507
 * Modifies specified account.
508
 *
509
 * @param int $id ID of account to be modified.
510
 * @param string $username New user name.
511
 * @param string $fullname New full name.
512
 * @param string $email New email address.
513
 * @param string $description New description.
514
 * @param bool $is_admin Whether the account should have administration privileges (see 'is_admin' DBO field).
515
 * @param bool $is_disabled Whether the account should be disabled (see 'is_disabled' DBO field).
516
 * @param int $locks_count New value of 'locks_count' DBO field.
517
 * @param bool $is_ldapuser Whether the account is LDAP one (FALSE by default, see 'is_ldapuser' DBO field).
518
 * @return int Error code:
519
 * <ul>
520
 * <li>{@link NO_ERROR} - account is successfully modified</li>
521
 * <li>{@link ERROR_ALREADY_EXISTS} - another account with specified user name already exists</li>
522
 * </ul>
523
 */
524
function account_modify ($id, $username, $fullname, $email, $description, $is_admin, $is_disabled, $locks_count, $is_ldapuser = FALSE)
525
{
526
    debug_write_log(DEBUG_TRACE, '[account_modify]');
527
    debug_write_log(DEBUG_DUMP,  '[account_modify] $id          = ' . $id);
528
    debug_write_log(DEBUG_DUMP,  '[account_modify] $username    = ' . $username);
529
    debug_write_log(DEBUG_DUMP,  '[account_modify] $fullname    = ' . $fullname);
530
    debug_write_log(DEBUG_DUMP,  '[account_modify] $email       = ' . $email);
531
    debug_write_log(DEBUG_DUMP,  '[account_modify] $description = ' . $description);
532
    debug_write_log(DEBUG_DUMP,  '[account_modify] $is_admin    = ' . $is_admin);
533
    debug_write_log(DEBUG_DUMP,  '[account_modify] $is_disabled = ' . $is_disabled);
534
    debug_write_log(DEBUG_DUMP,  '[account_modify] $locks_count = ' . $locks_count);
535
    debug_write_log(DEBUG_DUMP,  '[account_modify] $is_ldapuser = ' . $is_ldapuser);
536
537
    // Check that there is no account with the same user name, besides this one.
538
    $rs = dal_query('accounts/fndku.sql', $id, ustrtolower($username . ($is_ldapuser ? NULL : ACCOUNT_SUFFIX)));
539
540
    if ($rs->rows != 0)
541
    {
542
        debug_write_log(DEBUG_NOTICE, '[account_modify] Account already exists.');
543
        return ERROR_ALREADY_EXISTS;
544
    }
545
546
    // Modify the account.
547
    dal_query('accounts/modify.sql',
548
              $id,
549
              $username . ($is_ldapuser ? NULL : ACCOUNT_SUFFIX),
550
              $fullname,
551
              $email,
552
              ustrlen($description) == 0 ? NULL : $description,
553
              bool2sql($is_admin),
554
              bool2sql($is_disabled),
555
              $locks_count);
556
557
    return NO_ERROR;
558
}
559
560
/**
561
 * Creates new LDAP account in eTraxis database.
562
 *
563
 * The function searches on LDAP server for specified <i>username</i>.
564
 * If user is found, then his display name and email address are cached in eTraxis database.
565
 * If <i>password</i> is specified, then function also tries to authorize on LDAP server using specified <i>username</i> and <i>password</i>.
566
 * If authorization is failed, NULL is returned, even when user with specified <i>username</i> was successfully found.
567
 * On success ID of new registered account is returned.
568
 *
569
 * @param string $username User name for new account.
570
 * @param string $password Password of user.
571
 * @return int ID of new account on success, NULL otherwise.
572
 */
573
function account_register_ldapuser ($username, $passwd = NULL)
574
{
575
    debug_write_log(DEBUG_TRACE, '[account_register_ldapuser]');
576
    debug_write_log(DEBUG_DUMP,  '[account_register_ldapuser] $username = ' . $username);
577
578
    // Set default encoding of multibyte String library to UTF-8.
579
    mb_regex_encoding('UTF-8');
580
581
    // Find a user with specified user name on LDAP server.
582
    $id = NULL;
583
    $userinfo = ldap_finduser($username, $passwd);
584
585
    if (!is_null($userinfo))
586
    {
587
        debug_write_log(DEBUG_NOTICE, 'Active Directory account is found.');
588
589
        // Prepare list of LDAP admins
590
        $ldap_admins = mb_split(',', ustrtolower(LDAP_ADMINS));
591
592
        foreach ($ldap_admins as $key => $ldap_admin)
593
        {
594
            $ldap_admins[$key] = trim($ldap_admin);
595
        }
596
597
        // Check whether this LDAP user is already registered in eTraxis database.
598
        $rs = dal_query('accounts/fndk.sql', ustrtolower($username));
599
600
        // This LDAP user was never registered in eTraxis database before.
601
        if ($rs->rows == 0)
602
        {
603
            debug_write_log(DEBUG_NOTICE, 'Register Active Directory account in eTraxis database.');
604
605
            // Create an account in eTraxis database for this LDAP user.
606
            account_create($username,
607
                           $userinfo[0],
608
                           $userinfo[1],
609
                           '',
610
                           'Active Directory account',
611
                           in_array(ustrtolower($username), $ldap_admins),
612
                           0, LANG_DEFAULT, TRUE);
0 ignored issues
show
0 is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
613
614
            $rs = dal_query('accounts/fndk.sql', ustrtolower($username));
615
            $id = $rs->fetch('account_id');
616
        }
617
        // This LDAP user is already registered in eTraxis database.
618
        else
619
        {
620
            debug_write_log(DEBUG_NOTICE, 'Update Active Directory account in eTraxis database.');
621
622
            $id = $rs->fetch('account_id');
623
624
            // Update an account of this LDAP user in eTraxis database.
625
            account_modify($id,
626
                           $username,
627
                           $userinfo[0],
628
                           $userinfo[1],
629
                           'Active Directory account',
630
                           in_array(ustrtolower($username), $ldap_admins),
631
                           0, 0, TRUE);
0 ignored issues
show
0 is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
632
        }
633
    }
634
    else
635
    {
636
        debug_write_log(DEBUG_NOTICE, 'Cannot find Active Directory account.');
637
    }
638
639
    return $id;
640
}
641
642
/**
643
 * Checks whether account can be deleted.
644
 *
645
 * @param int $id ID of account to be deleted.
646
 * @return bool TRUE if account can be deleted, FALSE otherwise.
647
 */
648
function is_account_removable ($id)
649
{
650
    debug_write_log(DEBUG_TRACE, '[is_account_removable]');
651
    debug_write_log(DEBUG_DUMP,  '[is_account_removable] $id = ' . $id);
652
653
    // default "root" account must not be deleted
654
    if ($id == 1) return FALSE;
655
656
    $rs = dal_query('accounts/efndc.sql', $id);
657
658
    return ($rs->fetch(0) == 0);
659
}
660
661
/**
662
 * Deletes specified account.
663
 *
664
 * @param int $id ID of account to be deleted.
665
 * @return int Always {@link NO_ERROR}.
666
 */
667
function account_delete ($id)
668
{
669
    debug_write_log(DEBUG_TRACE, '[account_delete]');
670
    debug_write_log(DEBUG_DUMP,  '[account_delete] $id = ' . $id);
671
672
    dal_query('records/unreadall.sql',  $id);
673
    dal_query('accounts/rdelall.sql',   $id);
674
    dal_query('accounts/rsdelall.sql',  $id);
675
    dal_query('accounts/sdelall.sql',   $id);
676
    dal_query('accounts/setview.sql',   $id, NULL);
677
    dal_query('accounts/vfdelall.sql',  $id);
678
    dal_query('accounts/vcdelall.sql',  $id);
679
    dal_query('accounts/vdelall.sql',   $id);
680
    dal_query('accounts/ffdelall.sql',  $id);
681
    dal_query('accounts/ftdelall.sql',  $id);
682
    dal_query('accounts/fsdelall.sql',  $id);
683
    dal_query('accounts/fadelall.sql',  $id);
684
    dal_query('accounts/fa2delall.sql', $id);
685
    dal_query('accounts/fshdelall.sql', $id);
686
    dal_query('accounts/fdelall.sql',   $id);
687
    dal_query('accounts/msdelall.sql',  $id);
688
    dal_query('accounts/delete.sql',    $id);
689
690
    return NO_ERROR;
691
}
692
693
/**
694
 * Validates new password which user has entered to change his current one.
695
 *
696
 * @param string $passwd1 First password entry.
697
 * @param string $passwd2 Second password entry.
698
 * @return int Error code:
699
 * <ul>
700
 * <li>{@link NO_ERROR} - entered password is valid</li>
701
 * <li>{@link ERROR_INCOMPLETE_FORM} - at least one of password entries is empty</li>
702
 * <li>{@link ERROR_PASSWORDS_DO_NOT_MATCH} - entered password entries are not equal</li>
703
 * <li>{@link ERROR_PASSWORD_TOO_SHORT} - entered password is too short (see {@link MIN_PASSWORD_LENGTH})</li>
704
 * </ul>
705
 */
706
function password_validate ($passwd1, $passwd2)
707
{
708
    debug_write_log(DEBUG_TRACE, '[password_validate]');
709
710
    if (ustrlen($passwd1) == 0 ||
711
        ustrlen($passwd2) == 0)
712
    {
713
        debug_write_log(DEBUG_NOTICE, '[password_validate] At least one required field is empty.');
714
        return ERROR_INCOMPLETE_FORM;
715
    }
716
717
    if ($passwd1 != $passwd2)
718
    {
719
        debug_write_log(DEBUG_NOTICE, '[password_validate] Passwords do not match.');
720
        return ERROR_PASSWORDS_DO_NOT_MATCH;
721
    }
722
723
    if (ustrlen($passwd1) < MIN_PASSWORD_LENGTH)
724
    {
725
        debug_write_log(DEBUG_NOTICE, '[password_validate] Password is too short.');
726
        return ERROR_PASSWORD_TOO_SHORT;
727
    }
728
729
    return NO_ERROR;
730
}
731
732
/**
733
 * Change password of specified user.
734
 *
735
 * @param int $id ID of user account.
736
 * @param string $passwd New password string.
737
 * @return int Always {@link NO_ERROR}.
738
 */
739 View Code Duplication
function password_change ($id, $passwd)
740
{
741
    debug_write_log(DEBUG_TRACE, '[password_change]');
742
    debug_write_log(DEBUG_DUMP,  '[password_change] $id = ' . $id);
743
744
    dal_query('accounts/passwd.sql',
745
              $id,
746
              base64_encode(sha1($passwd, TRUE)),
747
              time());
748
749
    return NO_ERROR;
750
}
751
752
/**
753
 * Change UI language for specified user.
754
 *
755
 * @param int $id ID of user account.
756
 * @param int $locale New UI language (see 'locale' DBO field).
757
 * @return int Always {@link NO_ERROR}.
758
 */
759
function locale_change ($id, $locale)
760
{
761
    debug_write_log(DEBUG_TRACE, '[locale_change]');
762
    debug_write_log(DEBUG_DUMP,  '[locale_change] $id     = ' . $id);
763
    debug_write_log(DEBUG_DUMP,  '[locale_change] $locale = ' . $locale);
764
765
    global $locale_info;
766
767
    if (array_key_exists($locale, $locale_info))
768
    {
769
        dal_query('accounts/locale.sql', $id, $locale);
770
    }
771
772
    return NO_ERROR;
773
}
774
775
/**
776
 * Set current user's view to specified one, or restore default view if NULL is specified.
777
 *
778
 * @param int $view_id View ID (NULL by default).
779
 * @return int Always {@link NO_ERROR}.
780
 */
781
function account_set_view ($view_id = NULL)
782
{
783
    debug_write_log(DEBUG_TRACE, '[account_set_view]');
784
    debug_write_log(DEBUG_DUMP,  '[account_set_view] $view_id = ' . $view_id);
785
786
    dal_query('accounts/setview.sql', $_SESSION[VAR_USERID], is_null($view_id) ? NULL : $view_id);
787
788
    return NO_ERROR;
789
}
790
791
/**
792
 * Exports accounts of specified group IDs to XML code (see also {@link template_import}).
793
 *
794
 * @param array Array with Group IDs.
795
 * @return string Generated XML code for accounts found.
796
 */
797
function accounts_export ($groups)
798
{
799
    debug_write_log(DEBUG_TRACE, '[accounts_export]');
800
801
    // Remove duplicated group IDs.
802
    $groups = array_unique($groups);
803
804
    if (count($groups) == 0)
805
    {
806
        return NULL;
807
    }
808
809
    // List members of all global and local project groups.
810
    $rs = dal_query('groups/mamongs2.sql', implode(',', $groups));
811
812
    $xml_a = NULL;
813
814
    if ($rs->rows != 0)
815
    {
816
        $xml_a = "  <accounts>\n";
817
818
        // Add XML code for all enumerated accounts.
819
        while (($account = $rs->fetch()))
820
        {
821
            // Add XML code for general account information.
822
            $xml_a .= sprintf("    <account username=\"%s\" fullname=\"%s\" email=\"%s\" description=\"%s\" type=\"%s\" admin=\"%s\" disabled=\"%s\" locale=\"%s\"/>\n",
823
                              account_get_username($account['username'], FALSE),
824
                              ustr2html($account['fullname']),
825
                              ustr2html($account['email']),
826
                              ustr2html($account['description']),
827
                              ($account['is_ldapuser'] ? 'ldap' : 'local'),
828
                              ($account['is_admin']    ? 'yes'  : 'no'),
829
                              ($account['is_disabled'] ? 'yes'  : 'no'),
830
                              get_html_resource(RES_LOCALE_ID, $account['locale']));
831
        }
832
833
        $xml_a .= "  </accounts>\n";
834
    }
835
836
    return $xml_a;
837
}
838
839
?>
840