Conditions | 44 |
Paths | > 20000 |
Total Lines | 229 |
Code Lines | 129 |
Lines | 0 |
Ratio | 0 % |
Changes | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
1 | <?php |
||
41 | function check_user_password_ldap($usertotest, $passwordtotest, $entitytotest) |
||
42 | { |
||
43 | global $db, $conf, $langs; |
||
44 | global $dolibarr_main_auth_ldap_host, $dolibarr_main_auth_ldap_port; |
||
45 | global $dolibarr_main_auth_ldap_version, $dolibarr_main_auth_ldap_servertype; |
||
46 | global $dolibarr_main_auth_ldap_login_attribute, $dolibarr_main_auth_ldap_dn; |
||
47 | global $dolibarr_main_auth_ldap_admin_login, $dolibarr_main_auth_ldap_admin_pass; |
||
48 | global $dolibarr_main_auth_ldap_filter; |
||
49 | global $dolibarr_main_auth_ldap_debug; |
||
50 | |||
51 | // Force master entity in transversal mode |
||
52 | $entity = $entitytotest; |
||
53 | if (isModEnabled('multicompany') && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) { |
||
54 | $entity = 1; |
||
55 | } |
||
56 | |||
57 | $login = ''; |
||
58 | $resultFetchUser = ''; |
||
59 | |||
60 | if (!function_exists("ldap_connect")) { |
||
61 | dol_syslog("functions_ldap::check_user_password_ldap Authentication KO failed to connect to LDAP. LDAP functions are disabled on this PHP", LOG_ERR); |
||
62 | sleep(1); |
||
63 | |||
64 | // Load translation files required by the page |
||
65 | $langs->loadLangs(array('main', 'other')); |
||
66 | |||
67 | $_SESSION["dol_loginmesg"] = $langs->transnoentitiesnoconv("ErrorLDAPFunctionsAreDisabledOnThisPHP") . ' ' . $langs->transnoentitiesnoconv("TryAnotherConnectionMode"); |
||
68 | return ''; |
||
69 | } |
||
70 | |||
71 | if ($usertotest) { |
||
72 | dol_syslog("functions_ldap::check_user_password_ldap usertotest=" . $usertotest . " passwordtotest=" . preg_replace('/./', '*', $passwordtotest) . " entitytotest=" . $entitytotest); |
||
73 | |||
74 | // If test username/password asked, we define $test=false and $login var if ok, set $_SESSION["dol_loginmesg"] if ko |
||
75 | $ldaphost = $dolibarr_main_auth_ldap_host; |
||
76 | $ldapport = $dolibarr_main_auth_ldap_port; |
||
77 | $ldapversion = $dolibarr_main_auth_ldap_version; |
||
78 | $ldapservertype = (empty($dolibarr_main_auth_ldap_servertype) ? 'openldap' : $dolibarr_main_auth_ldap_servertype); |
||
79 | |||
80 | $ldapuserattr = $dolibarr_main_auth_ldap_login_attribute; |
||
81 | $ldapdn = $dolibarr_main_auth_ldap_dn; |
||
82 | $ldapadminlogin = $dolibarr_main_auth_ldap_admin_login; |
||
83 | $ldapadminpass = $dolibarr_main_auth_ldap_admin_pass; |
||
84 | $ldapdebug = ((empty($dolibarr_main_auth_ldap_debug) || $dolibarr_main_auth_ldap_debug == "false") ? false : true); |
||
85 | |||
86 | if ($ldapdebug) { |
||
87 | print "DEBUG: Logging LDAP steps<br>\n"; |
||
88 | } |
||
89 | |||
90 | $ldap = new Ldap(); |
||
91 | $ldap->server = explode(',', $ldaphost); |
||
92 | $ldap->serverPort = $ldapport; |
||
93 | $ldap->ldapProtocolVersion = $ldapversion; |
||
94 | $ldap->serverType = $ldapservertype; |
||
95 | $ldap->searchUser = $ldapadminlogin; |
||
96 | $ldap->searchPassword = $ldapadminpass; |
||
97 | |||
98 | if ($ldapdebug) { |
||
99 | dol_syslog("functions_ldap::check_user_password_ldap Server:" . implode(',', $ldap->server) . ", Port:" . $ldap->serverPort . ", Protocol:" . $ldap->ldapProtocolVersion . ", Type:" . $ldap->serverType); |
||
100 | dol_syslog("functions_ldap::check_user_password_ldap uid/samaccountname=" . $ldapuserattr . ", dn=" . $ldapdn . ", Admin:" . $ldap->searchUser . ", Pass:" . dol_trunc($ldap->searchPassword, 3)); |
||
101 | print "DEBUG: Server:" . implode(',', $ldap->server) . ", Port:" . $ldap->serverPort . ", Protocol:" . $ldap->ldapProtocolVersion . ", Type:" . $ldap->serverType . "<br>\n"; |
||
102 | print "DEBUG: uid/samaccountname=" . $ldapuserattr . ", dn=" . $ldapdn . ", Admin:" . $ldap->searchUser . ", Pass:" . dol_trunc($ldap->searchPassword, 3) . "<br>\n"; |
||
103 | } |
||
104 | |||
105 | $resultFetchLdapUser = 0; |
||
106 | |||
107 | // Define $userSearchFilter |
||
108 | $userSearchFilter = ""; |
||
109 | if (empty($dolibarr_main_auth_ldap_filter)) { |
||
110 | $userSearchFilter = "(" . $ldapuserattr . "=" . $usertotest . ")"; |
||
111 | } else { |
||
112 | // @phan-suppress-next-line PhanPluginSuspiciousParamOrderInternal |
||
113 | $userSearchFilter = str_replace('%1%', $usertotest, $dolibarr_main_auth_ldap_filter); |
||
114 | } |
||
115 | |||
116 | // If admin login or ldap auth filter provided |
||
117 | // Code to get user in LDAP from an admin connection (may differ from user connection, done later) |
||
118 | if ($ldapadminlogin || $dolibarr_main_auth_ldap_filter) { |
||
119 | $result = $ldap->connectBind(); |
||
120 | if ($result > 0) { |
||
121 | $resultFetchLdapUser = $ldap->fetch($usertotest, $userSearchFilter); |
||
122 | //dol_syslog('functions_ldap::check_user_password_ldap resultFetchLdapUser='.$resultFetchLdapUser); |
||
123 | if ($resultFetchLdapUser > 0 && $ldap->pwdlastset == 0) { // If ok but password need to be reset |
||
124 | dol_syslog('functions_ldap::check_user_password_ldap ' . $usertotest . ' must change password next logon'); |
||
125 | if ($ldapdebug) { |
||
126 | print "DEBUG: User " . $usertotest . " must change password<br>\n"; |
||
127 | } |
||
128 | $ldap->unbind(); |
||
129 | sleep(1); // Anti brut force protection. Must be same delay when user and password are not valid. |
||
130 | $langs->load('ldap'); |
||
131 | $_SESSION["dol_loginmesg"] = $langs->transnoentitiesnoconv("YouMustChangePassNextLogon", $usertotest, $ldap->domainFQDN); |
||
132 | return ''; |
||
133 | } |
||
134 | } else { |
||
135 | if ($ldapdebug) { |
||
136 | print "DEBUG: " . $ldap->error . "<br>\n"; |
||
137 | } |
||
138 | } |
||
139 | $ldap->unbind(); |
||
140 | } |
||
141 | |||
142 | // Forge LDAP user and password to test with them |
||
143 | // If LDAP need a dn with login like "uid=jbloggs,ou=People,dc=foo,dc=com", default dn may work even if previous code with |
||
144 | // admin login no executed. |
||
145 | $ldap->searchUser = $ldapuserattr . "=" . $usertotest . "," . $ldapdn; // Default dn (will work if LDAP accept a dn with login value inside) |
||
146 | // But if LDAP need a dn with name like "cn=Jhon Bloggs,ou=People,dc=foo,dc=com", previous part must have been executed to have |
||
147 | // dn detected into ldapUserDN. |
||
148 | if ($resultFetchLdapUser && !empty($ldap->ldapUserDN)) { |
||
149 | $ldap->searchUser = $ldap->ldapUserDN; |
||
150 | } |
||
151 | $ldap->searchPassword = $passwordtotest; |
||
152 | |||
153 | // Test with this->seachUser and this->searchPassword |
||
154 | //print $resultFetchLdapUser."-".$ldap->ldapUserDN."-".$ldap->searchUser.'-'.$ldap->searchPassword;exit; |
||
155 | $result = $ldap->connectBind(); |
||
156 | if ($result > 0) { |
||
157 | if ($result == 2) { // Connection is ok for user/pass into LDAP |
||
158 | $login = $usertotest; |
||
159 | dol_syslog("functions_ldap::check_user_password_ldap $login authentication ok"); |
||
160 | // For the case, we search the user id using a search key without the login (but using other fields like id), |
||
161 | // we need to get the real login to use in the ldap answer. |
||
162 | if (getDolGlobalString('LDAP_FIELD_LOGIN') && !empty($ldap->login)) { |
||
163 | $login = $ldap->login; |
||
164 | dol_syslog("functions_ldap::check_user_password_ldap login is now $login (LDAP_FIELD_LOGIN=" . getDolGlobalString('LDAP_FIELD_LOGIN') . ")"); |
||
165 | } |
||
166 | |||
167 | require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/date.lib.php'; |
||
168 | |||
169 | // Note: Test on date validity is done later natively with isNotIntoValidityDateRange() by core after calling checkLoginPassEntity() that call this method |
||
170 | |||
171 | // ldap2dolibarr synchronisation |
||
172 | if ($login && !empty($conf->ldap->enabled) && getDolGlobalInt('LDAP_SYNCHRO_ACTIVE') == Ldap::SYNCHRO_LDAP_TO_DOLIBARR) { // ldap2dolibarr synchronization |
||
173 | dol_syslog("functions_ldap::check_user_password_ldap Sync ldap2dolibarr"); |
||
174 | |||
175 | // On charge les attributes du user ldap |
||
176 | if ($ldapdebug) { |
||
177 | print "DEBUG: login ldap = " . $login . "<br>\n"; |
||
178 | } |
||
179 | $resultFetchLdapUser = $ldap->fetch($login, $userSearchFilter); |
||
180 | |||
181 | if ($ldapdebug) { |
||
182 | print "DEBUG: UACF = " . implode(',', $ldap->uacf) . "<br>\n"; |
||
183 | } |
||
184 | if ($ldapdebug) { |
||
185 | print "DEBUG: pwdLastSet = " . dol_print_date($ldap->pwdlastset, 'day') . "<br>\n"; |
||
186 | } |
||
187 | if ($ldapdebug) { |
||
188 | print "DEBUG: badPasswordTime = " . dol_print_date($ldap->badpwdtime, 'day') . "<br>\n"; |
||
189 | } |
||
190 | |||
191 | // On recherche le user dolibarr en fonction de son SID ldap (only for Active Directory) |
||
192 | $sid = null; |
||
193 | if (getDolGlobalString('LDAP_SERVER_TYPE') == "activedirectory") { |
||
194 | $sid = $ldap->getObjectSid($login); |
||
195 | if ($ldapdebug) { |
||
196 | print "DEBUG: sid = " . $sid . "<br>\n"; |
||
197 | } |
||
198 | } |
||
199 | |||
200 | $usertmp = new User($db); |
||
201 | $resultFetchUser = $usertmp->fetch('', $login, $sid, 1, ($entitytotest > 0 ? $entitytotest : -1)); |
||
202 | if ($resultFetchUser > 0) { |
||
203 | dol_syslog("functions_ldap::check_user_password_ldap Sync user found user id=" . $usertmp->id); |
||
204 | // Verify if the login changed and update the Dolibarr attributes |
||
205 | |||
206 | if ($usertmp->login != $ldap->login && $ldap->login) { |
||
207 | $usertmp->login = $ldap->login; |
||
208 | $usertmp->update($usertmp); |
||
209 | // TODO What to do if the update fails because the login already exists for another account. |
||
210 | } |
||
211 | |||
212 | //$resultUpdate = $usertmp->update_ldap2dolibarr($ldap); |
||
213 | } |
||
214 | |||
215 | unset($usertmp); |
||
216 | } |
||
217 | |||
218 | if (isModEnabled('multicompany')) { // We must check entity (even if sync is not active) |
||
219 | global $mc; |
||
220 | |||
221 | $usertmp = new User($db); |
||
222 | $usertmp->fetch('', $login); |
||
223 | if (is_object($mc)) { |
||
224 | $ret = $mc->checkRight($usertmp->id, $entitytotest); |
||
225 | if ($ret < 0) { |
||
226 | dol_syslog("functions_ldap::check_user_password_ldap Authentication KO entity '" . $entitytotest . "' not allowed for user id '" . $usertmp->id . "'", LOG_NOTICE); |
||
227 | $login = ''; // force authentication failure |
||
228 | } |
||
229 | unset($usertmp); |
||
230 | } |
||
231 | } |
||
232 | } |
||
233 | if ($result == 1) { |
||
234 | dol_syslog("functions_ldap::check_user_password_ldap Authentication KO bad user/password for '" . $usertotest . "'", LOG_NOTICE); |
||
235 | sleep(1); // Anti brut force protection. Must be same delay when user and password are not valid. |
||
236 | |||
237 | // Load translation files required by the page |
||
238 | $langs->loadLangs(array('main', 'other')); |
||
239 | |||
240 | $_SESSION["dol_loginmesg"] = $langs->transnoentitiesnoconv("ErrorBadLoginPassword"); |
||
241 | } |
||
242 | } else { |
||
243 | /* Login failed. Return false, together with the error code and text from |
||
244 | ** the LDAP server. The common error codes and reasons are listed below : |
||
245 | ** (for iPlanet, other servers may differ) |
||
246 | ** 19 - Account locked out (too many invalid login attempts) |
||
247 | ** 32 - User does not exist |
||
248 | ** 49 - Wrong password |
||
249 | ** 53 - Account inactive (manually locked out by administrator) |
||
250 | */ |
||
251 | dol_syslog("functions_ldap::check_user_password_ldap Authentication KO failed to connect to LDAP for '" . $usertotest . "'", LOG_NOTICE); |
||
252 | if (is_resource($ldap->connection) || is_object($ldap->connection)) { // If connection ok but bind ko |
||
253 | // @phan-suppress-next-line PhanTypeMismatchArgumentInternal Expects LDAP\Connection, not 'resource' |
||
254 | $ldap->ldapErrorCode = ldap_errno($ldap->connection); |
||
255 | // @phan-suppress-next-line PhanTypeMismatchArgumentInternal Expects LDAP\Connection, not 'resource' |
||
256 | $ldap->ldapErrorText = ldap_error($ldap->connection); |
||
257 | dol_syslog("functions_ldap::check_user_password_ldap " . $ldap->ldapErrorCode . " " . $ldap->ldapErrorText); |
||
258 | } |
||
259 | sleep(1); // Anti brut force protection. Must be same delay when user and password are not valid. |
||
260 | |||
261 | // Load translation files required by the page |
||
262 | $langs->loadLangs(array('main', 'other', 'errors')); |
||
263 | $_SESSION["dol_loginmesg"] = ($ldap->error ? $ldap->error : $langs->transnoentitiesnoconv("ErrorBadLoginPassword")); |
||
264 | } |
||
265 | |||
266 | $ldap->unbind(); |
||
267 | } |
||
268 | |||
269 | return $login; |
||
270 | } |
||
271 |