Subversion Repositories Applications.papyrus

Rev

Rev 1173 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1173 Rev 1713
1
<?php
1
<?php
2
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
2
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
3
 
3
 
4
/**
4
/**
5
 * Storage driver for use against PEAR DB
5
 * Storage driver for use against PEAR DB
6
 *
6
 *
7
 * PHP versions 4 and 5
7
 * PHP versions 4 and 5
8
 *
8
 *
9
 * LICENSE: This source file is subject to version 3.01 of the PHP license
9
 * LICENSE: This source file is subject to version 3.01 of the PHP license
10
 * that is available through the world-wide-web at the following URI:
10
 * that is available through the world-wide-web at the following URI:
11
 * http://www.php.net/license/3_01.txt.  If you did not receive a copy of
11
 * http://www.php.net/license/3_01.txt.  If you did not receive a copy of
12
 * the PHP License and are unable to obtain it through the web, please
12
 * the PHP License and are unable to obtain it through the web, please
13
 * send a note to license@php.net so we can mail you a copy immediately.
13
 * send a note to license@php.net so we can mail you a copy immediately.
14
 *
14
 *
15
 * @category   Authentication
15
 * @category   Authentication
16
 * @package    Auth
16
 * @package    Auth
17
 * @author     Martin Jansen <mj@php.net>
17
 * @author     Martin Jansen <mj@php.net>
18
 * @author     Adam Ashley <aashley@php.net>
18
 * @author     Adam Ashley <aashley@php.net>
19
 * @copyright  2001-2006 The PHP Group
19
 * @copyright  2001-2006 The PHP Group
20
 * @license    http://www.php.net/license/3_01.txt  PHP License 3.01
20
 * @license    http://www.php.net/license/3_01.txt  PHP License 3.01
21
 * @version    CVS: $Id: DB.php,v 1.2 2006-12-14 15:04:28 jp_milcent Exp $
21
 * @version    CVS: $Id: DB.php,v 1.3 2007-11-19 15:11:00 jp_milcent Exp $
22
 * @link       http://pear.php.net/package/Auth
22
 * @link       http://pear.php.net/package/Auth
23
 */
23
 */
24
 
24
 
25
/**
25
/**
26
 * Include Auth_Container base class
26
 * Include Auth_Container base class
27
 */
27
 */
28
require_once 'Auth/Container.php';
28
require_once 'Auth/Container.php';
29
/**
29
/**
30
 * Include PEAR DB
30
 * Include PEAR DB
31
 */
31
 */
32
require_once 'DB.php';
32
require_once 'DB.php';
33
 
33
 
34
/**
34
/**
35
 * Storage driver for fetching login data from a database
35
 * Storage driver for fetching login data from a database
36
 *
36
 *
37
 * This storage driver can use all databases which are supported
37
 * This storage driver can use all databases which are supported
38
 * by the PEAR DB abstraction layer to fetch login data.
38
 * by the PEAR DB abstraction layer to fetch login data.
39
 *
39
 *
40
 * @category   Authentication
40
 * @category   Authentication
41
 * @package    Auth
41
 * @package    Auth
42
 * @author     Martin Jansen <mj@php.net>
42
 * @author     Martin Jansen <mj@php.net>
43
 * @author     Adam Ashley <aashley@php.net>
43
 * @author     Adam Ashley <aashley@php.net>
44
 * @copyright  2001-2006 The PHP Group
44
 * @copyright  2001-2006 The PHP Group
45
 * @license    http://www.php.net/license/3_01.txt  PHP License 3.01
45
 * @license    http://www.php.net/license/3_01.txt  PHP License 3.01
46
 * @version    Release: 1.4.3  File: $Revision: 1.2 $
46
 * @version    Release: 1.5.4  File: $Revision: 1.3 $
47
 * @link       http://pear.php.net/package/Auth
47
 * @link       http://pear.php.net/package/Auth
48
 */
48
 */
49
class Auth_Container_DB extends Auth_Container
49
class Auth_Container_DB extends Auth_Container
50
{
50
{
51
 
51
 
52
    // {{{ properties
52
    // {{{ properties
53
 
53
 
54
    /**
54
    /**
55
     * Additional options for the storage container
55
     * Additional options for the storage container
56
     * @var array
56
     * @var array
57
     */
57
     */
58
    var $options = array();
58
    var $options = array();
59
 
59
 
60
    /**
60
    /**
61
     * DB object
61
     * DB object
62
     * @var object
62
     * @var object
63
     */
63
     */
64
    var $db = null;
64
    var $db = null;
65
    var $dsn = '';
65
    var $dsn = '';
66
 
66
 
67
    /**
67
    /**
68
     * User that is currently selected from the DB.
68
     * User that is currently selected from the DB.
69
     * @var string
69
     * @var string
70
     */
70
     */
71
    var $activeUser = '';
71
    var $activeUser = '';
72
 
72
 
73
    // }}}
73
    // }}}
74
    // {{{ Auth_Container_DB [constructor]
74
    // {{{ Auth_Container_DB [constructor]
75
 
75
 
76
    /**
76
    /**
77
     * Constructor of the container class
77
     * Constructor of the container class
78
     *
78
     *
79
     * Save the initial options passed to the container. Initiation of the DB
79
     * Save the initial options passed to the container. Initiation of the DB
80
     * connection is no longer performed here and is only done when needed.
80
     * connection is no longer performed here and is only done when needed.
81
     *
81
     *
82
     * @param  string Connection data or DB object
82
     * @param  string Connection data or DB object
83
     * @return object Returns an error object if something went wrong
83
     * @return object Returns an error object if something went wrong
84
     */
84
     */
85
    function Auth_Container_DB($dsn)
85
    function Auth_Container_DB($dsn)
86
    {
86
    {
87
        $this->_setDefaults();
87
        $this->_setDefaults();
88
 
88
 
89
        if (is_array($dsn)) {
89
        if (is_array($dsn)) {
90
            $this->_parseOptions($dsn);
90
            $this->_parseOptions($dsn);
91
 
91
 
92
            if (empty($this->options['dsn'])) {
92
            if (empty($this->options['dsn'])) {
93
                PEAR::raiseError('No connection parameters specified!');
93
                PEAR::raiseError('No connection parameters specified!');
94
            }
94
            }
95
        } else {
95
        } else {
96
            $this->options['dsn'] = $dsn;
96
            $this->options['dsn'] = $dsn;
97
        }
97
        }
98
    }
98
    }
99
 
99
 
100
    // }}}
100
    // }}}
101
    // {{{ _connect()
101
    // {{{ _connect()
102
 
102
 
103
    /**
103
    /**
104
     * Connect to database by using the given DSN string
104
     * Connect to database by using the given DSN string
105
     *
105
     *
106
     * @access private
106
     * @access private
107
     * @param  string DSN string
107
     * @param  string DSN string
108
     * @return mixed  Object on error, otherwise bool
108
     * @return mixed  Object on error, otherwise bool
109
     */
109
     */
110
    function _connect($dsn)
110
    function _connect($dsn)
111
    {
111
    {
-
 
112
        $this->log('Auth_Container_DB::_connect() called.', AUTH_LOG_DEBUG);
-
 
113
 
112
        if (is_string($dsn) || is_array($dsn)) {
114
        if (is_string($dsn) || is_array($dsn)) {
113
            $this->db = DB::Connect($dsn, $this->options['db_options']);
115
            $this->db = DB::Connect($dsn, $this->options['db_options']);
114
        } elseif (is_subclass_of($dsn, 'db_common')) {
116
        } elseif (is_subclass_of($dsn, 'db_common')) {
115
            $this->db = $dsn;
117
            $this->db = $dsn;
116
        } elseif (DB::isError($dsn)) {
118
        } elseif (DB::isError($dsn)) {
117
            return PEAR::raiseError($dsn->getMessage(), $dsn->getCode());
119
            return PEAR::raiseError($dsn->getMessage(), $dsn->getCode());
118
        } else {
120
        } else {
119
            return PEAR::raiseError('The given dsn was not valid in file ' . __FILE__ . ' at line ' . __LINE__,
121
            return PEAR::raiseError('The given dsn was not valid in file ' . __FILE__ . ' at line ' . __LINE__,
120
                                    41,
122
                                    41,
121
                                    PEAR_ERROR_RETURN,
123
                                    PEAR_ERROR_RETURN,
122
                                    null,
124
                                    null,
123
                                    null
125
                                    null
124
                                    );
126
                                    );
125
        }
127
        }
126
 
128
 
127
        if (DB::isError($this->db) || PEAR::isError($this->db)) {
129
        if (DB::isError($this->db) || PEAR::isError($this->db)) {
128
            return PEAR::raiseError($this->db->getMessage(), $this->db->getCode());
130
            return PEAR::raiseError($this->db->getMessage(), $this->db->getCode());
129
        } else {
131
        } else {
130
            return true;
132
            return true;
131
        }
133
        }
132
    }
134
    }
133
 
135
 
134
    // }}}
136
    // }}}
135
    // {{{ _prepare()
137
    // {{{ _prepare()
136
 
138
 
137
    /**
139
    /**
138
     * Prepare database connection
140
     * Prepare database connection
139
     *
141
     *
140
     * This function checks if we have already opened a connection to
142
     * This function checks if we have already opened a connection to
141
     * the database. If that's not the case, a new connection is opened.
143
     * the database. If that's not the case, a new connection is opened.
142
     *
144
     *
143
     * @access private
145
     * @access private
144
     * @return mixed True or a DB error object.
146
     * @return mixed True or a DB error object.
145
     */
147
     */
146
    function _prepare()
148
    function _prepare()
147
    {
149
    {
148
        if (!DB::isConnection($this->db)) {
150
        if (!DB::isConnection($this->db)) {
149
            $res = $this->_connect($this->options['dsn']);
151
            $res = $this->_connect($this->options['dsn']);
150
            if (DB::isError($res) || PEAR::isError($res)) {
152
            if (DB::isError($res) || PEAR::isError($res)) {
151
                return $res;
153
                return $res;
152
            }
154
            }
153
        }
155
        }
154
        if ($this->options['auto_quote'] && $this->db->dsn['phptype'] != 'sqlite') {
156
        if ($this->options['auto_quote'] && $this->db->dsn['phptype'] != 'sqlite') {
155
            $this->options['final_table'] = $this->db->quoteIdentifier($this->options['table']);
157
            $this->options['final_table'] = $this->db->quoteIdentifier($this->options['table']);
156
            $this->options['final_usernamecol'] = $this->db->quoteIdentifier($this->options['usernamecol']);
158
            $this->options['final_usernamecol'] = $this->db->quoteIdentifier($this->options['usernamecol']);
157
            $this->options['final_passwordcol'] = $this->db->quoteIdentifier($this->options['passwordcol']);
159
            $this->options['final_passwordcol'] = $this->db->quoteIdentifier($this->options['passwordcol']);
158
        } else {
160
        } else {
159
            $this->options['final_table'] = $this->options['table'];
161
            $this->options['final_table'] = $this->options['table'];
160
            $this->options['final_usernamecol'] = $this->options['usernamecol'];
162
            $this->options['final_usernamecol'] = $this->options['usernamecol'];
161
            $this->options['final_passwordcol'] = $this->options['passwordcol'];
163
            $this->options['final_passwordcol'] = $this->options['passwordcol'];
162
        }
164
        }
163
        return true;
165
        return true;
164
    }
166
    }
165
 
167
 
166
    // }}}
168
    // }}}
167
    // {{{ query()
169
    // {{{ query()
168
 
170
 
169
    /**
171
    /**
170
     * Prepare query to the database
172
     * Prepare query to the database
171
     *
173
     *
172
     * This function checks if we have already opened a connection to
174
     * This function checks if we have already opened a connection to
173
     * the database. If that's not the case, a new connection is opened.
175
     * the database. If that's not the case, a new connection is opened.
174
     * After that the query is passed to the database.
176
     * After that the query is passed to the database.
175
     *
177
     *
176
     * @access public
178
     * @access public
177
     * @param  string Query string
179
     * @param  string Query string
178
     * @return mixed  a DB_result object or DB_OK on success, a DB
180
     * @return mixed  a DB_result object or DB_OK on success, a DB
179
     *                or PEAR error on failure
181
     *                or PEAR error on failure
180
     */
182
     */
181
    function query($query)
183
    function query($query)
182
    {
184
    {
183
        $err = $this->_prepare();
185
        $err = $this->_prepare();
184
        if ($err !== true) {
186
        if ($err !== true) {
185
            return $err;
187
            return $err;
186
        }
188
        }
187
        return $this->db->query($query);
189
        return $this->db->query($query);
188
    }
190
    }
189
 
191
 
190
    // }}}
192
    // }}}
191
    // {{{ _setDefaults()
193
    // {{{ _setDefaults()
192
 
194
 
193
    /**
195
    /**
194
     * Set some default options
196
     * Set some default options
195
     *
197
     *
196
     * @access private
198
     * @access private
197
     * @return void
199
     * @return void
198
     */
200
     */
199
    function _setDefaults()
201
    function _setDefaults()
200
    {
202
    {
201
        $this->options['table']       = 'auth';
203
        $this->options['table']       = 'auth';
202
        $this->options['usernamecol'] = 'username';
204
        $this->options['usernamecol'] = 'username';
203
        $this->options['passwordcol'] = 'password';
205
        $this->options['passwordcol'] = 'password';
204
        $this->options['dsn']         = '';
206
        $this->options['dsn']         = '';
205
        $this->options['db_fields']   = '';
207
        $this->options['db_fields']   = '';
206
        $this->options['cryptType']   = 'md5';
208
        $this->options['cryptType']   = 'md5';
207
        $this->options['db_options']  = array();
209
        $this->options['db_options']  = array();
-
 
210
        $this->options['db_where']    = '';
208
        $this->options['auto_quote']  = true;
211
        $this->options['auto_quote']  = true;
209
    }
212
    }
210
 
213
 
211
    // }}}
214
    // }}}
212
    // {{{ _parseOptions()
215
    // {{{ _parseOptions()
213
 
216
 
214
    /**
217
    /**
215
     * Parse options passed to the container class
218
     * Parse options passed to the container class
216
     *
219
     *
217
     * @access private
220
     * @access private
218
     * @param  array
221
     * @param  array
219
     */
222
     */
220
    function _parseOptions($array)
223
    function _parseOptions($array)
221
    {
224
    {
222
        foreach ($array as $key => $value) {
225
        foreach ($array as $key => $value) {
223
            if (isset($this->options[$key])) {
226
            if (isset($this->options[$key])) {
224
                $this->options[$key] = $value;
227
                $this->options[$key] = $value;
225
            }
228
            }
226
        }
229
        }
227
    }
230
    }
228
 
231
 
229
    // }}}
232
    // }}}
230
    // {{{ _quoteDBFields()
233
    // {{{ _quoteDBFields()
231
 
234
 
232
    /**
235
    /**
233
     * Quote the db_fields option to avoid the possibility of SQL injection.
236
     * Quote the db_fields option to avoid the possibility of SQL injection.
234
     *
237
     *
235
     * @access private
238
     * @access private
236
     * @return string A properly quoted string that can be concatenated into a
239
     * @return string A properly quoted string that can be concatenated into a
237
     * SELECT clause.
240
     * SELECT clause.
238
     */
241
     */
239
    function _quoteDBFields()
242
    function _quoteDBFields()
240
    {
243
    {
241
        if (isset($this->options['db_fields'])) {
244
        if (isset($this->options['db_fields'])) {
242
            if (is_array($this->options['db_fields'])) {
245
            if (is_array($this->options['db_fields'])) {
243
                if ($this->options['auto_quote']) {
246
                if ($this->options['auto_quote']) {
244
                    $fields = array();
247
                    $fields = array();
245
                    foreach ($this->options['db_fields'] as $field) {
248
                    foreach ($this->options['db_fields'] as $field) {
246
                        $fields[] = $this->db->quoteIdentifier($field);
249
                        $fields[] = $this->db->quoteIdentifier($field);
247
                    }
250
                    }
248
                    return implode(', ', $fields);
251
                    return implode(', ', $fields);
249
                } else {
252
                } else {
250
                    return implode(', ', $this->options['db_fields']);
253
                    return implode(', ', $this->options['db_fields']);
251
                }
254
                }
252
            } else {
255
            } else {
253
                if (strlen($this->options['db_fields']) > 0) {
256
                if (strlen($this->options['db_fields']) > 0) {
254
                    if ($this->options['auto_quote']) {
257
                    if ($this->options['auto_quote']) {
255
                        return $this->db->quoteIdentifier($this->options['db_fields']);
258
                        return $this->db->quoteIdentifier($this->options['db_fields']);
256
                    } else {
259
                    } else {
257
                        return $this->options['db_fields'];
260
                        return $this->options['db_fields'];
258
                    }
261
                    }
259
                }
262
                }
260
            }
263
            }
261
        }
264
        }
262
 
265
 
263
        return '';
266
        return '';
264
    }
267
    }
265
    
268
 
266
    // }}}
269
    // }}}
267
    // {{{ fetchData()
270
    // {{{ fetchData()
268
 
271
 
269
    /**
272
    /**
270
     * Get user information from database
273
     * Get user information from database
271
     *
274
     *
272
     * This function uses the given username to fetch
275
     * This function uses the given username to fetch
273
     * the corresponding login data from the database
276
     * the corresponding login data from the database
274
     * table. If an account that matches the passed username
277
     * table. If an account that matches the passed username
275
     * and password is found, the function returns true.
278
     * and password is found, the function returns true.
276
     * Otherwise it returns false.
279
     * Otherwise it returns false.
277
     *
280
     *
278
     * @param   string Username
281
     * @param   string Username
279
     * @param   string Password
282
     * @param   string Password
280
     * @param   boolean If true password is secured using a md5 hash
283
     * @param   boolean If true password is secured using a md5 hash
281
     *                  the frontend and auth are responsible for making sure the container supports
284
     *                  the frontend and auth are responsible for making sure the container supports
282
     *                  challenge response password authentication
285
     *                  challenge response password authentication
283
     * @return  mixed  Error object or boolean
286
     * @return  mixed  Error object or boolean
284
     */
287
     */
285
    function fetchData($username, $password, $isChallengeResponse=false)
288
    function fetchData($username, $password, $isChallengeResponse=false)
286
    {
289
    {
-
 
290
        $this->log('Auth_Container_DB::fetchData() called.', AUTH_LOG_DEBUG);
287
        // Prepare for a database query
291
        // Prepare for a database query
288
        $err = $this->_prepare();
292
        $err = $this->_prepare();
289
        if ($err !== true) {
293
        if ($err !== true) {
290
            return PEAR::raiseError($err->getMessage(), $err->getCode());
294
            return PEAR::raiseError($err->getMessage(), $err->getCode());
291
        }
295
        }
292
 
296
 
293
        // Find if db_fields contains a *, if so assume all columns are selected
297
        // Find if db_fields contains a *, if so assume all columns are selected
294
        if (is_string($this->options['db_fields'])
298
        if (is_string($this->options['db_fields'])
295
            && strstr($this->options['db_fields'], '*')) {
299
            && strstr($this->options['db_fields'], '*')) {
296
            $sql_from = "*";
300
            $sql_from = "*";
297
        } else {
301
        } else {
298
            $sql_from = $this->options['final_usernamecol'].
302
            $sql_from = $this->options['final_usernamecol'].
299
                ", ".$this->options['final_passwordcol'];
303
                ", ".$this->options['final_passwordcol'];
300
 
304
 
301
            if (strlen($fields = $this->_quoteDBFields()) > 0) {
305
            if (strlen($fields = $this->_quoteDBFields()) > 0) {
302
                $sql_from .= ', '.$fields;
306
                $sql_from .= ', '.$fields;
303
            }
307
            }
304
        }
308
        }
305
 
309
 
306
        $query = "SELECT ".$sql_from.
310
        $query = "SELECT ".$sql_from.
307
                " FROM ".$this->options['final_table'].
311
                " FROM ".$this->options['final_table'].
308
                " WHERE ".$this->options['final_usernamecol']." = ".$this->db->quoteSmart($username);
312
                " WHERE ".$this->options['final_usernamecol']." = ".$this->db->quoteSmart($username);
-
 
313
 
-
 
314
        // check if there is an optional parameter db_where
-
 
315
        if ($this->options['db_where'] != '') {
-
 
316
            // there is one, so add it to the query
-
 
317
            $query .= " AND ".$this->options['db_where'];
-
 
318
        }
-
 
319
 
-
 
320
        $this->log('Running SQL against DB: '.$query, AUTH_LOG_DEBUG);
309
 
321
 
310
        $res = $this->db->getRow($query, null, DB_FETCHMODE_ASSOC);
322
        $res = $this->db->getRow($query, null, DB_FETCHMODE_ASSOC);
311
 
323
 
312
        if (DB::isError($res)) {
324
        if (DB::isError($res)) {
313
            return PEAR::raiseError($res->getMessage(), $res->getCode());
325
            return PEAR::raiseError($res->getMessage(), $res->getCode());
314
        }
326
        }
315
 
327
 
316
        if (!is_array($res)) {
328
        if (!is_array($res)) {
317
            $this->activeUser = '';
329
            $this->activeUser = '';
318
            return false;
330
            return false;
319
        }
331
        }
320
 
332
 
321
        // Perform trimming here before the hashihg
333
        // Perform trimming here before the hashihg
322
        $password = trim($password, "\r\n");
334
        $password = trim($password, "\r\n");
323
        $res[$this->options['passwordcol']] = trim($res[$this->options['passwordcol']], "\r\n");
335
        $res[$this->options['passwordcol']] = trim($res[$this->options['passwordcol']], "\r\n");
324
 
336
 
325
        // If using Challenge Response md5 the pass with the secret
337
        // If using Challenge Response md5 the pass with the secret
326
        if ($isChallengeResponse) {
338
        if ($isChallengeResponse) {
327
            $res[$this->options['passwordcol']] = md5($res[$this->options['passwordcol']]
339
            $res[$this->options['passwordcol']] = md5($res[$this->options['passwordcol']]
328
                    .$this->_auth_obj->session['loginchallenege']);
340
                    .$this->_auth_obj->session['loginchallenege']);
329
            
341
 
330
            // UGLY cannot avoid without modifying verifyPassword
342
            // UGLY cannot avoid without modifying verifyPassword
331
            if ($this->options['cryptType'] == 'md5') {
343
            if ($this->options['cryptType'] == 'md5') {
332
                $res[$this->options['passwordcol']] = md5($res[$this->options['passwordcol']]);
344
                $res[$this->options['passwordcol']] = md5($res[$this->options['passwordcol']]);
333
            }
345
            }
334
            
346
 
335
            //print " Hashed Password [{$res[$this->options['passwordcol']]}]<br/>\n";
347
            //print " Hashed Password [{$res[$this->options['passwordcol']]}]<br/>\n";
336
        }
348
        }
337
 
349
 
338
        if ($this->verifyPassword($password,
350
        if ($this->verifyPassword($password,
339
                                  $res[$this->options['passwordcol']],
351
                                  $res[$this->options['passwordcol']],
340
                                  $this->options['cryptType'])) {
352
                                  $this->options['cryptType'])) {
341
            // Store additional field values in the session
353
            // Store additional field values in the session
342
            foreach ($res as $key => $value) {
354
            foreach ($res as $key => $value) {
343
                if ($key == $this->options['passwordcol'] ||
355
                if ($key == $this->options['passwordcol'] ||
344
                    $key == $this->options['usernamecol']) {
356
                    $key == $this->options['usernamecol']) {
345
                    continue;
357
                    continue;
346
                }
358
                }
-
 
359
 
-
 
360
                $this->log('Storing additional field: '.$key, AUTH_LOG_DEBUG);
-
 
361
 
347
                // Use reference to the auth object if exists
362
                // Use reference to the auth object if exists
348
                // This is because the auth session variable can change so a 
363
                // This is because the auth session variable can change so a
349
                // static call to setAuthData does not make sence
364
                // static call to setAuthData does not make sence
350
                $this->_auth_obj->setAuthData($key, $value);
365
                $this->_auth_obj->setAuthData($key, $value);
351
            }
366
            }
352
            return true;
367
            return true;
353
        }
368
        }
354
        $this->activeUser = $res[$this->options['usernamecol']];
369
        $this->activeUser = $res[$this->options['usernamecol']];
355
        return false;
370
        return false;
356
    }
371
    }
357
 
372
 
358
    // }}}
373
    // }}}
359
    // {{{ listUsers()
374
    // {{{ listUsers()
360
 
375
 
361
    /**
376
    /**
362
     * Returns a list of users from the container
377
     * Returns a list of users from the container
363
     *
378
     *
364
     * @return mixed
379
     * @return mixed
365
     * @access public
380
     * @access public
366
     */
381
     */
367
    function listUsers()
382
    function listUsers()
368
    {
383
    {
-
 
384
        $this->log('Auth_Container_DB::listUsers() called.', AUTH_LOG_DEBUG);
369
        $err = $this->_prepare();
385
        $err = $this->_prepare();
370
        if ($err !== true) {
386
        if ($err !== true) {
371
            return PEAR::raiseError($err->getMessage(), $err->getCode());
387
            return PEAR::raiseError($err->getMessage(), $err->getCode());
372
        }
388
        }
373
 
389
 
374
        $retVal = array();
390
        $retVal = array();
375
 
391
 
376
        // Find if db_fields contains a *, if so assume all col are selected
392
        // Find if db_fields contains a *, if so assume all col are selected
377
        if (   is_string($this->options['db_fields'])
393
        if (   is_string($this->options['db_fields'])
378
            && strstr($this->options['db_fields'], '*')) {
394
            && strstr($this->options['db_fields'], '*')) {
379
            $sql_from = "*";
395
            $sql_from = "*";
380
        } else {
396
        } else {
381
            $sql_from = $this->options['final_usernamecol'].
397
            $sql_from = $this->options['final_usernamecol'].
382
                ", ".$this->options['final_passwordcol'];
398
                ", ".$this->options['final_passwordcol'];
383
 
399
 
384
            if (strlen($fields = $this->_quoteDBFields()) > 0) {
400
            if (strlen($fields = $this->_quoteDBFields()) > 0) {
385
                $sql_from .= ', '.$fields;
401
                $sql_from .= ', '.$fields;
386
            }
402
            }
387
        }
403
        }
388
 
404
 
389
        $query = sprintf("SELECT %s FROM %s",
405
        $query = sprintf("SELECT %s FROM %s",
390
                         $sql_from,
406
                         $sql_from,
391
                         $this->options['final_table']
407
                         $this->options['final_table']
392
                         );
408
                         );
-
 
409
 
-
 
410
        // check if there is an optional parameter db_where
-
 
411
        if ($this->options['db_where'] != '') {
-
 
412
            // there is one, so add it to the query
-
 
413
            $query .= " WHERE ".$this->options['db_where'];
-
 
414
        }
-
 
415
 
-
 
416
        $this->log('Running SQL against DB: '.$query, AUTH_LOG_DEBUG);
-
 
417
 
393
        $res = $this->db->getAll($query, null, DB_FETCHMODE_ASSOC);
418
        $res = $this->db->getAll($query, null, DB_FETCHMODE_ASSOC);
394
 
419
 
395
        if (DB::isError($res)) {
420
        if (DB::isError($res)) {
396
            return PEAR::raiseError($res->getMessage(), $res->getCode());
421
            return PEAR::raiseError($res->getMessage(), $res->getCode());
397
        } else {
422
        } else {
398
            foreach ($res as $user) {
423
            foreach ($res as $user) {
399
                $user['username'] = $user[$this->options['usernamecol']];
424
                $user['username'] = $user[$this->options['usernamecol']];
400
                $retVal[] = $user;
425
                $retVal[] = $user;
401
            }
426
            }
402
        }
427
        }
-
 
428
        $this->log('Found '.count($retVal).' users.', AUTH_LOG_DEBUG);
403
        return $retVal;
429
        return $retVal;
404
    }
430
    }
405
 
431
 
406
    // }}}
432
    // }}}
407
    // {{{ addUser()
433
    // {{{ addUser()
408
 
434
 
409
    /**
435
    /**
410
     * Add user to the storage container
436
     * Add user to the storage container
411
     *
437
     *
412
     * @access public
438
     * @access public
413
     * @param  string Username
439
     * @param  string Username
414
     * @param  string Password
440
     * @param  string Password
415
     * @param  mixed  Additional information that are stored in the DB
441
     * @param  mixed  Additional information that are stored in the DB
416
     *
442
     *
417
     * @return mixed True on success, otherwise error object
443
     * @return mixed True on success, otherwise error object
418
     */
444
     */
419
    function addUser($username, $password, $additional = "")
445
    function addUser($username, $password, $additional = "")
420
    {
446
    {
-
 
447
        $this->log('Auth_Container_DB::addUser() called.', AUTH_LOG_DEBUG);
421
        $err = $this->_prepare();
448
        $err = $this->_prepare();
422
        if ($err !== true) {
449
        if ($err !== true) {
423
            return PEAR::raiseError($err->getMessage(), $err->getCode());
450
            return PEAR::raiseError($err->getMessage(), $err->getCode());
424
        }
451
        }
425
 
452
 
426
        if (   isset($this->options['cryptType']) 
453
        if (   isset($this->options['cryptType'])
427
            && $this->options['cryptType'] == 'none') {
454
            && $this->options['cryptType'] == 'none') {
428
            $cryptFunction = 'strval';
455
            $cryptFunction = 'strval';
429
        } elseif (   isset($this->options['cryptType']) 
456
        } elseif (   isset($this->options['cryptType'])
430
                  && function_exists($this->options['cryptType'])) {
457
                  && function_exists($this->options['cryptType'])) {
431
            $cryptFunction = $this->options['cryptType'];
458
            $cryptFunction = $this->options['cryptType'];
432
        } else {
459
        } else {
433
            $cryptFunction = 'md5';
460
            $cryptFunction = 'md5';
434
        }
461
        }
435
 
462
 
436
        $password = $cryptFunction($password);
463
        $password = $cryptFunction($password);
437
 
464
 
438
        $additional_key   = '';
465
        $additional_key   = '';
439
        $additional_value = '';
466
        $additional_value = '';
440
 
467
 
441
        if (is_array($additional)) {
468
        if (is_array($additional)) {
442
            foreach ($additional as $key => $value) {
469
            foreach ($additional as $key => $value) {
443
                if ($this->options['auto_quote']) {
470
                if ($this->options['auto_quote']) {
444
                    $additional_key .= ', ' . $this->db->quoteIdentifier($key);
471
                    $additional_key .= ', ' . $this->db->quoteIdentifier($key);
445
                } else {
472
                } else {
446
                    $additional_key .= ', ' . $key;
473
                    $additional_key .= ', ' . $key;
447
                }
474
                }
448
                $additional_value .= ", " . $this->db->quoteSmart($value);
475
                $additional_value .= ", " . $this->db->quoteSmart($value);
449
            }
476
            }
450
        }
477
        }
451
 
478
 
452
        $query = sprintf("INSERT INTO %s (%s, %s%s) VALUES (%s, %s%s)",
479
        $query = sprintf("INSERT INTO %s (%s, %s%s) VALUES (%s, %s%s)",
453
                         $this->options['final_table'],
480
                         $this->options['final_table'],
454
                         $this->options['final_usernamecol'],
481
                         $this->options['final_usernamecol'],
455
                         $this->options['final_passwordcol'],
482
                         $this->options['final_passwordcol'],
456
                         $additional_key,
483
                         $additional_key,
457
                         $this->db->quoteSmart($username),
484
                         $this->db->quoteSmart($username),
458
                         $this->db->quoteSmart($password),
485
                         $this->db->quoteSmart($password),
459
                         $additional_value
486
                         $additional_value
460
                         );
487
                         );
-
 
488
 
-
 
489
        $this->log('Running SQL against DB: '.$query, AUTH_LOG_DEBUG);
461
 
490
 
462
        $res = $this->query($query);
491
        $res = $this->query($query);
463
 
492
 
464
        if (DB::isError($res)) {
493
        if (DB::isError($res)) {
465
            return PEAR::raiseError($res->getMessage(), $res->getCode());
494
            return PEAR::raiseError($res->getMessage(), $res->getCode());
466
        } else {
495
        } else {
467
            return true;
496
            return true;
468
        }
497
        }
469
    }
498
    }
470
 
499
 
471
    // }}}
500
    // }}}
472
    // {{{ removeUser()
501
    // {{{ removeUser()
473
 
502
 
474
    /**
503
    /**
475
     * Remove user from the storage container
504
     * Remove user from the storage container
476
     *
505
     *
477
     * @access public
506
     * @access public
478
     * @param  string Username
507
     * @param  string Username
479
     *
508
     *
480
     * @return mixed True on success, otherwise error object
509
     * @return mixed True on success, otherwise error object
481
     */
510
     */
482
    function removeUser($username)
511
    function removeUser($username)
483
    {
512
    {
-
 
513
        $this->log('Auth_Container_DB::removeUser() called.', AUTH_LOG_DEBUG);
-
 
514
 
484
        $err = $this->_prepare();
515
        $err = $this->_prepare();
485
        if ($err !== true) {
516
        if ($err !== true) {
486
            return PEAR::raiseError($err->getMessage(), $err->getCode());
517
            return PEAR::raiseError($err->getMessage(), $err->getCode());
487
        }
518
        }
-
 
519
 
-
 
520
        // check if there is an optional parameter db_where
-
 
521
        if ($this->options['db_where'] != '') {
-
 
522
            // there is one, so add it to the query
-
 
523
            $where = " AND ".$this->options['db_where'];
-
 
524
        } else {
-
 
525
            $where = '';
-
 
526
        }
488
 
527
 
489
        $query = sprintf("DELETE FROM %s WHERE %s = %s",
528
        $query = sprintf("DELETE FROM %s WHERE %s = %s %s",
490
                         $this->options['final_table'],
529
                         $this->options['final_table'],
491
                         $this->options['final_usernamecol'],
530
                         $this->options['final_usernamecol'],
-
 
531
                         $this->db->quoteSmart($username),
492
                         $this->db->quoteSmart($username)
532
                         $where
-
 
533
                         );
-
 
534
 
493
                         );
535
        $this->log('Running SQL against DB: '.$query, AUTH_LOG_DEBUG);
494
 
536
 
495
        $res = $this->query($query);
537
        $res = $this->query($query);
496
 
538
 
497
        if (DB::isError($res)) {
539
        if (DB::isError($res)) {
498
           return PEAR::raiseError($res->getMessage(), $res->getCode());
540
           return PEAR::raiseError($res->getMessage(), $res->getCode());
499
        } else {
541
        } else {
500
          return true;
542
          return true;
501
        }
543
        }
502
    }
544
    }
503
 
545
 
504
    // }}}
546
    // }}}
505
    // {{{ changePassword()
547
    // {{{ changePassword()
506
 
548
 
507
    /**
549
    /**
508
     * Change password for user in the storage container
550
     * Change password for user in the storage container
509
     *
551
     *
510
     * @param string Username
552
     * @param string Username
511
     * @param string The new password (plain text)
553
     * @param string The new password (plain text)
512
     */
554
     */
513
    function changePassword($username, $password)
555
    function changePassword($username, $password)
514
    {
556
    {
-
 
557
        $this->log('Auth_Container_DB::changePassword() called.', AUTH_LOG_DEBUG);
515
        $err = $this->_prepare();
558
        $err = $this->_prepare();
516
        if ($err !== true) {
559
        if ($err !== true) {
517
            return PEAR::raiseError($err->getMessage(), $err->getCode());
560
            return PEAR::raiseError($err->getMessage(), $err->getCode());
518
        }
561
        }
519
 
562
 
520
        if (   isset($this->options['cryptType']) 
563
        if (   isset($this->options['cryptType'])
521
            && $this->options['cryptType'] == 'none') {
564
            && $this->options['cryptType'] == 'none') {
522
            $cryptFunction = 'strval';
565
            $cryptFunction = 'strval';
523
        } elseif (   isset($this->options['cryptType']) 
566
        } elseif (   isset($this->options['cryptType'])
524
                  && function_exists($this->options['cryptType'])) {
567
                  && function_exists($this->options['cryptType'])) {
525
            $cryptFunction = $this->options['cryptType'];
568
            $cryptFunction = $this->options['cryptType'];
526
        } else {
569
        } else {
527
            $cryptFunction = 'md5';
570
            $cryptFunction = 'md5';
528
        }
571
        }
529
 
572
 
530
        $password = $cryptFunction($password);
573
        $password = $cryptFunction($password);
-
 
574
 
-
 
575
        // check if there is an optional parameter db_where
-
 
576
        if ($this->options['db_where'] != '') {
-
 
577
            // there is one, so add it to the query
-
 
578
            $where = " AND ".$this->options['db_where'];
-
 
579
        } else {
-
 
580
            $where = '';
-
 
581
        }
531
 
582
 
532
        $query = sprintf("UPDATE %s SET %s = %s WHERE %s = %s",
583
        $query = sprintf("UPDATE %s SET %s = %s WHERE %s = %s %s",
533
                         $this->options['final_table'],
584
                         $this->options['final_table'],
534
                         $this->options['final_passwordcol'],
585
                         $this->options['final_passwordcol'],
535
                         $this->db->quoteSmart($password),
586
                         $this->db->quoteSmart($password),
536
                         $this->options['final_usernamecol'],
587
                         $this->options['final_usernamecol'],
537
                         $this->db->quoteSmart($username)
588
                         $this->db->quoteSmart($username),
-
 
589
                         $where
538
                         );
590
                         );
-
 
591
 
-
 
592
        $this->log('Running SQL against DB: '.$query, AUTH_LOG_DEBUG);
539
 
593
 
540
        $res = $this->query($query);
594
        $res = $this->query($query);
541
 
595
 
542
        if (DB::isError($res)) {
596
        if (DB::isError($res)) {
543
            return PEAR::raiseError($res->getMessage(), $res->getCode());
597
            return PEAR::raiseError($res->getMessage(), $res->getCode());
544
        } else {
598
        } else {
545
            return true;
599
            return true;
546
        }
600
        }
547
    }
601
    }
548
 
602
 
549
    // }}}
603
    // }}}
550
    // {{{ supportsChallengeResponse()
604
    // {{{ supportsChallengeResponse()
551
 
605
 
552
    /**
606
    /**
553
     * Determine if this container supports
607
     * Determine if this container supports
554
     * password authentication with challenge response
608
     * password authentication with challenge response
555
     *
609
     *
556
     * @return bool
610
     * @return bool
557
     * @access public
611
     * @access public
558
     */
612
     */
559
    function supportsChallengeResponse()
613
    function supportsChallengeResponse()
560
    {
614
    {
561
        return in_array($this->options['cryptType'], array('md5', 'none', ''));
615
        return in_array($this->options['cryptType'], array('md5', 'none', ''));
562
    }
616
    }
563
 
617
 
564
    // }}}
618
    // }}}
565
    // {{{ getCryptType()
619
    // {{{ getCryptType()
566
 
620
 
567
    /**
621
    /**
568
      * Returns the selected crypt type for this container
622
      * Returns the selected crypt type for this container
569
      */
623
      */
570
    function getCryptType()
624
    function getCryptType()
571
    {
625
    {
572
        return($this->options['cryptType']);
626
        return($this->options['cryptType']);
573
    }
627
    }
574
 
628
 
575
    // }}}
629
    // }}}
576
 
630
 
577
}
631
}
578
?>
632
?>