Welcome to mirror list, hosted at ThFree Co, Russian Federation.

smb.php « lib « user_external - github.com/nextcloud/apps.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: ffc2ddd2c12abc855c042f30e34224e91b040c63 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
<?php
/**
 * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
 * This file is licensed under the Affero General Public License version 3 or
 * later.
 * See the COPYING-README file.
 */

/**
 * User authentication via samba (smbclient)
 *
 * @category Apps
 * @package  UserExternal
 * @author   Robin Appelman <icewind@owncloud.com>
 * @license  http://www.gnu.org/licenses/agpl AGPL
 * @link     http://github.com/owncloud/apps
 */
class OC_User_SMB extends \OCA\user_external\Base{
	private $host;

	const SMBCLIENT = 'smbclient -L';
	const LOGINERROR = 'NT_STATUS_LOGON_FAILURE';

	/**
	 * Create new samba authentication provider
	 *
	 * @param string $host Hostname or IP of windows machine
	 */
	public function __construct($host) {
		parent::__construct($host);
		$this->host=$host;
	}

	/**
	 * @param string $uid
	 * @param string $password
	 * @return bool
	 */
	private function tryAuthentication($uid, $password) {
		$uidEscaped = escapeshellarg($uid);
		$password = escapeshellarg($password);
		$command = self::SMBCLIENT.' '.escapeshellarg('//' . $this->host . '/dummy').' -U'.$uidEscaped.'%'.$password;
		$lastline = exec($command, $output, $retval);
		if ($retval === 127) {
			OCP\Util::writeLog(
				'user_external', 'ERROR: smbclient executable missing',
				OCP\Util::ERROR
			);
			return false;
		} else if (strpos($lastline, self::LOGINERROR) !== false) {
			//normal login error
			return false;
		} else if (strpos($lastline, 'NT_STATUS_BAD_NETWORK_NAME') !== false) {
			//login on minor error
			goto login;
		} else if ($retval != 0) {
			//some other error
			OCP\Util::writeLog(
				'user_external', 'ERROR: smbclient error: ' . trim($lastline),
				OCP\Util::ERROR
			);
			return false;
		} else {
			login:
			return $uid;
		}
	}

	/**
	 * Check if the password is correct without logging in the user
	 *
	 * @param string $uid      The username
	 * @param string $password The password
	 *
	 * @return true/false
	 */
	public function checkPassword($uid, $password) {
		// Check with an invalid password, if the user authenticates then fail
		$attemptWithInvalidPassword = $this->tryAuthentication($uid, base64_encode($password));
		if(is_string($attemptWithInvalidPassword)) {
			return false;
		}

		// Check with valid password
		$attemptWithValidPassword = $this->tryAuthentication($uid, $password);
		if(is_string($attemptWithValidPassword)) {
			$this->storeUser($uid);
			return $uid;
		}

		return false;
	}
}