1<?php
2
3class phpListAdminAuthentication
4{
5    public $name = 'Default phpList Authentication';
6    public $version = 0.1;
7    public $authors = 'Michiel Dethmers';
8    public $description = 'Provides authentication to phpList using the internal phpList administration database';
9
10    /**
11     * validateLogin, verify that the login credentials are correct.
12     *
13     * @param string $login    the login field
14     * @param string $password the password
15     *
16     * @return array
17     *               index 0 -> false if login failed, index of the administrator if successful
18     *               index 1 -> error message when login fails
19     *
20     * eg
21     *    return array(5,'OK'); // -> login successful for admin 5
22     *    return array(0,'Incorrect login details'); // login failed
23     */
24    public function validateLogin($login, $password)
25    {
26        $query = sprintf('select password, disabled, id from %s where loginname = "%s"', $GLOBALS['tables']['admin'],
27            sql_escape($login));
28        $req = Sql_Query($query);
29        $admindata = Sql_Fetch_Assoc($req);
30        $encryptedPass = hash(HASH_ALGO, $password);
31        $passwordDB = $admindata['password'];
32        //Password encryption verification.
33        if (strlen($passwordDB) < $GLOBALS['hash_length']) { // Passwords are encrypted but the actual is not.
34            //Encrypt the actual DB password before performing the validation below.
35            $encryptedPassDB = hash(HASH_ALGO, $passwordDB);
36            $query = sprintf('update %s set password = "%s" where loginname = "%s"', $GLOBALS['tables']['admin'],
37                $encryptedPassDB, sql_escape($login));
38            $passwordDB = $encryptedPassDB;
39            $req = Sql_Query($query);
40        }
41
42        if(empty($login)||($password=="")){
43            return array(0, s('Please enter your credentials.'));
44        }
45        if ($admindata['disabled']) {
46            return array(0, s('your account has been disabled'));
47        }
48        if (
49            !empty($passwordDB) && $encryptedPass === $passwordDB
50        ) {
51            return array($admindata['id'], 'OK');
52        }
53         else {
54            if (!empty($GLOBALS['admin_auth_module'])) {
55                Error(s('Admin authentication has changed, please update your admin module'),
56                    'https://resources.phplist.com/documentation/errors/adminauthchange');
57                return;
58                }
59        return array(0, s('incorrect password'));
60
61        }
62
63
64    }
65
66    public function getPassword($email)
67    {
68        $email = preg_replace("/[;,\"\']/", '', $email);
69        $req = Sql_Query('select email,password,loginname from '.$GLOBALS['tables']['admin'].' where email = "'.sql_escape($email).'"');
70        if (Sql_Affected_Rows()) {
71            $row = Sql_Fetch_Row($req);
72
73            return $row[1];
74        }
75    }
76
77    /**
78     * validateAccount, verify that the logged in admin is still valid.
79     *
80     * this allows verification that the admin still exists and is valid
81     *
82     * @param int $id the ID of the admin as provided by validateLogin
83     *
84     * @return array
85     *               index 0 -> false if failed, true if successful
86     *               index 1 -> error message when validation fails
87     *
88     * eg
89     *    return array(1,'OK'); // -> admin valid
90     *    return array(0,'No such account'); // admin failed
91     */
92    public function validateAccount($id)
93    {
94        /* can only do this after upgrade, which means
95       * that the first login will always fail
96      */
97
98        $query = sprintf('select id, disabled,password from %s where id = %d', $GLOBALS['tables']['admin'], $id);
99        $data = Sql_Fetch_Row_Query($query);
100        if (!$data[0]) {
101            return array(0, s('No such account'));
102        } elseif ($data[1]) {
103            return array(0, s('your account has been disabled'));
104        }
105
106        //# do this separately from above, to avoid lock out when the DB hasn't been upgraded.
107        //# so, ignore the error
108        $query = sprintf('select privileges from %s where id = %d', $GLOBALS['tables']['admin'], $id);
109        $req = Sql_Query($query);
110        if ($req) {
111            $data = Sql_Fetch_Row($req);
112        } else {
113            $data = array();
114        }
115
116        if (!empty($data[0])) {
117            $_SESSION['privileges'] = unserialize($data[0]);
118        }
119
120        return array(1, 'OK');
121    }
122
123    /**
124     * adminName.
125     *
126     * Name of the currently logged in administrator
127     * Use for logging, eg "subscriber updated by XXXX"
128     * and to display ownership of lists
129     *
130     * @param int $id ID of the admin
131     *
132     * @return string;
133     */
134    public function adminName($id)
135    {
136        $req = Sql_Fetch_Row_Query(sprintf('select loginname from %s where id = %d', $GLOBALS['tables']['admin'], $id));
137
138        return $req[0] ? $req[0] : s('Nobody');
139    }
140
141    /**
142     * adminEmail.
143     *
144     * Email address of the currently logged in administrator
145     * used to potentially pre-fill the "From" field in a campaign
146     *
147     * @param int $id ID of the admin
148     *
149     * @return string;
150     */
151    public function adminEmail($id)
152    {
153        $req = Sql_Fetch_Row_Query(sprintf('select email from %s where id = %d', $GLOBALS['tables']['admin'], $id));
154
155        return $req[0] ? $req[0] : '';
156    }
157
158    /**
159     * adminIdForEmail.
160     *
161     * Return matching admin ID for an email address
162     * used for verifying the admin email address on a Forgot Password request
163     *
164     * @param string $email email address
165     *
166     * @return ID if found or false if not;
167     */
168    public function adminIdForEmail($email)
169    { //Obtain admin Id from a given email address.
170        $req = Sql_Fetch_Row_Query(sprintf('select id from %s where email = "%s"', $GLOBALS['tables']['admin'],
171            sql_escape($email)));
172
173        return $req[0] ? $req[0] : '';
174    }
175
176    /**
177     * isSuperUser.
178     *
179     * Return whether this admin is a super-admin or not
180     *
181     * @param int $id admin ID
182     *
183     * @return true if super-admin false if not
184     */
185    public function isSuperUser($id)
186    {
187        $req = Sql_Fetch_Row_Query(sprintf('select superuser from %s where id = %d', $GLOBALS['tables']['admin'], $id));
188
189        return $req[0];
190    }
191
192    /**
193     * listAdmins.
194     *
195     * Return array of admins in the system
196     * Used in the list page to allow assigning ownership to lists
197     *
198     * @param none
199     *
200     * @return array of admins
201     *               id => name
202     */
203    public function listAdmins()
204    {
205        $result = array();
206        $req = Sql_Query("select id,loginname from {$GLOBALS['tables']['admin']} order by loginname");
207        while ($row = Sql_Fetch_Array($req)) {
208            $result[$row['id']] = $row['loginname'];
209        }
210
211        return $result;
212    }
213}
214