Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
 
4
/**
5
 * File::Passwd::Common
6
 *
7
 * PHP versions 4 and 5
8
 *
9
 * LICENSE: This source file is subject to version 3.0 of the PHP license
10
 * that is available through the world-wide-web at the following URI:
11
 * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
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.
14
 *
15
 * @category   FileFormats
16
 * @package    File_Passwd
17
 * @author     Michael Wallner <mike@php.net>
18
 * @copyright  2003-2005 Michael Wallner
19
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
20
 * @version    CVS: $Id: Common.php,v 1.18 2005/03/30 18:33:33 mike Exp $
21
 * @link       http://pear.php.net/package/File_Passwd
22
 */
23
 
24
/**
25
* Requires System
26
*/
27
require_once 'System.php';
28
/**
29
* Requires File::Passwd
30
*/
31
require_once 'File/Passwd.php';
32
 
33
/**
34
* Baseclass for File_Passwd_* classes.
35
*
36
* <kbd><u>
37
*   Provides basic operations:
38
* </u></kbd>
39
*   o opening & closing
40
*   o locking & unlocking
41
*   o loading & saving
42
*   o check if user exist
43
*   o delete a certain user
44
*   o list users
45
*
46
* @author   Michael Wallner <mike@php.net>
47
* @package  File_Passwd
48
* @version  $Revision: 1.18 $
49
* @access   protected
50
* @internal extend this class for your File_Passwd_* class
51
*/
52
class File_Passwd_Common
53
{
54
    /**
55
    * passwd file
56
    *
57
    * @var string
58
    * @access protected
59
    */
60
    var $_file = 'passwd';
61
 
62
    /**
63
    * file content
64
    *
65
    * @var aray
66
    * @access protected
67
    */
68
    var $_contents = array();
69
 
70
    /**
71
    * users
72
    *
73
    * @var array
74
    * @access protected
75
    */
76
    var $_users = array();
77
 
78
    /**
79
    * PCRE for valid chars
80
    *
81
    * @var  string
82
    * @access   protected
83
    */
84
    var $_pcre = '/^[a-z]+[a-z0-9_-]*$/i';
85
 
86
    /**
87
    * Constructor (ZE2)
88
    *
89
    * @access protected
90
    * @param  string    $file   path to passwd file
91
    */
92
    function __construct($file = 'passwd')
93
    {
94
        $this->setFile($file);
95
    }
96
 
97
    /**
98
    * Parse the content of the file
99
    *
100
    * You must overwrite this method in your File_Passwd_* class.
101
    *
102
    * @abstract
103
    * @internal
104
    * @access public
105
    * @return object    PEAR_Error
106
    */
107
    function parse()
108
    {
109
        return PEAR::raiseError(
110
            sprintf(FILE_PASSWD_E_METHOD_NOT_IMPLEMENTED_STR, 'parse'),
111
            FILE_PASSWD_E_METHOD_NOT_IMPLEMENTED
112
        );
113
    }
114
 
115
    /**
116
    * Apply changes and rewrite passwd file
117
    *
118
    * You must overwrite this method in your File_Passwd_* class.
119
    *
120
    * @abstract
121
    * @internal
122
    * @access public
123
    * @return object    PEAR_Error
124
    */
125
    function save()
126
    {
127
        return PEAR::raiseError(
128
            sprintf(FILE_PASSWD_E_METHOD_NOT_IMPLEMENTED_STR, 'save'),
129
            FILE_PASSWD_E_METHOD_NOT_IMPLEMENTED
130
        );
131
    }
132
 
133
    /**
134
    * Opens a file, locks it exclusively and returns the filehandle
135
    *
136
    * Returns a PEAR_Error if:
137
    *   o directory in which the file should reside couldn't be created
138
    *   o file couldn't be opened in the desired mode
139
    *   o file couldn't be locked exclusively
140
    *
141
    * @throws PEAR_Error
142
    * @access protected
143
    * @return mixed resource of type file handle or PEAR_Error
144
    * @param  string    $mode   the mode to open the file with
145
    */
146
    function &_open($mode, $file = null)
147
    {
148
        isset($file) or $file = $this->_file;
149
        $dir  = dirname($file);
150
        $lock = strstr($mode, 'r') ? LOCK_SH : LOCK_EX;
151
        if (!is_dir($dir) && !System::mkDir('-p -m 0755 ' . $dir)) {
152
            return PEAR::raiseError(
153
                sprintf(FILE_PASSWD_E_DIR_NOT_CREATED_STR, $dir),
154
                FILE_PASSWD_E_DIR_NOT_CREATED
155
            );
156
        }
157
        if (!is_resource($fh = @fopen($file, $mode))) {
158
            return PEAR::raiseError(
159
                sprintf(FILE_PASSWD_E_FILE_NOT_OPENED_STR, $file),
160
                FILE_PASSWD_E_FILE_NOT_OPENED
161
            );
162
        }
163
        if (!@flock($fh, $lock)) {
164
            fclose($fh);
165
            return PEAR::raiseError(
166
                sprintf(FILE_PASSWD_E_FILE_NOT_LOCKED_STR, $file),
167
                FILE_PASSWD_E_FILE_NOT_LOCKED
168
            );
169
        }
170
        return $fh;
171
    }
172
 
173
    /**
174
    * Closes a prior opened and locked file handle
175
    *
176
    * Returns a PEAR_Error if:
177
    *   o file couldn't be unlocked
178
    *   o file couldn't be closed
179
    *
180
    * @throws PEAR_Error
181
    * @access protected
182
    * @return mixed true on success or PEAR_Error
183
    * @param  resource  $file_handle    the file handle to operate on
184
    */
185
    function _close(&$file_handle)
186
    {
187
        if (!@flock($file_handle, LOCK_UN)) {
188
            return PEAR::raiseError(
189
                FILE_PASSWD_E_FILE_NOT_UNLOCKED_STR,
190
                FILE_PASSWD_E_FILE_NOT_UNLOCKED
191
            );
192
        }
193
        if (!@fclose($file_handle)) {
194
            return PEAR::raiseError(
195
                FILE_PASSWD_E_FILE_NOT_CLOSED_STR,
196
                FILE_PASSWD_E_FILE_NOT_CLOSED
197
            );
198
        }
199
        return true;
200
    }
201
 
202
    /**
203
    * Loads the file
204
    *
205
    * Returns a PEAR_Error if:
206
    *   o directory in which the file should reside couldn't be created
207
    *   o file couldn't be opened in read mode
208
    *   o file couldn't be locked exclusively
209
    *   o file couldn't be unlocked
210
    *   o file couldn't be closed
211
    *
212
    * @throws PEAR_Error
213
    * @access public
214
    * @return mixed true on success or PEAR_Error
215
    */
216
    function load()
217
    {
218
        $fh = &$this->_open('r');
219
        if (PEAR::isError($fh)) {
220
            return $fh;
221
        }
222
        $this->_contents = array();
223
        while ($line = fgets($fh)) {
224
            if (!preg_match('/^\s*#/', $line) && $line = trim($line)) {
225
                $this->_contents[] = $line;
226
            }
227
        }
228
        $e = $this->_close($fh);
229
        if (PEAR::isError($e)) {
230
            return $e;
231
        }
232
        return $this->parse();
233
    }
234
 
235
    /**
236
    * Save the modified content to the passwd file
237
    *
238
    * Returns a PEAR_Error if:
239
    *   o directory in which the file should reside couldn't be created
240
    *   o file couldn't be opened in write mode
241
    *   o file couldn't be locked exclusively
242
    *   o file couldn't be unlocked
243
    *   o file couldn't be closed
244
    *
245
    * @throws PEAR_Error
246
    * @access protected
247
    * @return mixed true on success or PEAR_Error
248
    */
249
    function _save($content)
250
    {
251
        $fh = &$this->_open('w');
252
        if (PEAR::isError($fh)) {
253
            return $fh;
254
        }
255
        fputs($fh, $content);
256
        return $this->_close($fh);
257
    }
258
 
259
    /**
260
    * Set path to passwd file
261
    *
262
    * @access public
263
    * @return void
264
    */
265
    function setFile($file)
266
    {
267
        $this->_file = $file;
268
    }
269
 
270
    /**
271
    * Get path of passwd file
272
    *
273
    * @access public
274
    * @return string
275
    */
276
    function getFile()
277
    {
278
        return $this->_file;
279
    }
280
 
281
    /**
282
    * Check if a certain user already exists
283
    *
284
    * @access public
285
    * @return bool
286
    * @param  string    $user   the name of the user to check if already exists
287
    */
288
    function userExists($user)
289
    {
290
        return isset($this->_users[$user]);
291
    }
292
 
293
    /**
294
    * Delete a certain user
295
    *
296
    * Returns a PEAR_Error if user doesn't exist.
297
    *
298
    * @throws PEAR_Error
299
    * @access public
300
    * @return mixed true on success or PEAR_Error
301
    * @param  string
302
    */
303
    function delUser($user)
304
    {
305
        if (!$this->userExists($user)) {
306
            return PEAR::raiseError(
307
                sprintf(FILE_PASSWD_E_EXISTS_NOT_STR, 'User ', $user),
308
                FILE_PASSWD_E_EXISTS_NOT
309
            );
310
        }
311
        unset($this->_users[$user]);
312
        return true;
313
    }
314
 
315
    /**
316
    * List user
317
    *
318
    * Returns a PEAR_Error if <var>$user</var> doesn't exist.
319
    *
320
    * @throws PEAR_Error
321
    * @access public
322
    * @return mixed array of a/all user(s) or PEAR_Error
323
    * @param  string    $user   the user to list or all users if empty
324
    */
325
    function listUser($user = '')
326
    {
327
        if (empty($user)) {
328
            return $this->_users;
329
        }
330
        if (!$this->userExists($user)) {
331
            return PEAR::raiseError(
332
                sprintf(FILE_PASSWD_E_EXISTS_NOT_STR, 'User ', $user),
333
                FILE_PASSWD_E_EXISTS_NOT
334
            );
335
        }
336
        return $this->_users[$user];
337
    }
338
 
339
    /**
340
    * Base method for File_Passwd::staticAuth()
341
    *
342
    * Returns a PEAR_Error if:
343
    *   o file doesn't exist
344
    *   o file couldn't be opened in read mode
345
    *   o file couldn't be locked exclusively
346
    *   o file couldn't be unlocked (only if auth fails)
347
    *   o file couldn't be closed (only if auth fails)
348
    *
349
    * @throws   PEAR_Error
350
    * @access   protected
351
    * @return   mixed       line of passwd file containing <var>$id</var>,
352
    *                       false if <var>$id</var> wasn't found or PEAR_Error
353
    * @param    string      $file   path to passwd file
354
    * @param    string      $id     user_id to search for
355
    * @param    string      $sep    field separator
356
    */
357
    function _auth($file, $id, $sep = ':')
358
    {
359
        $file = realpath($file);
360
        if (!is_file($file)) {
361
            return PEAR::raiseError("File '$file' couldn't be found.", 0);
362
        }
363
        $fh = &File_Passwd_Common::_open('r', $file);
364
        if (PEAR::isError($fh)) {
365
            return $fh;
366
        }
367
        $cmp = $id . $sep;
368
        $len = strlen($cmp);
369
        while ($line = fgets($fh)) {
370
            if (!strncmp($line, $cmp, $len)) {
371
                File_Passwd_Common::_close($fh);
372
                return trim($line);
373
            }
374
        }
375
        $e = File_Passwd_Common::_close($fh);
376
        if (PEAR::isError($e)) {
377
            return $e;
378
        }
379
        return false;
380
    }
381
}
382
?>