PageRenderTime 49ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/tine20/Tinebase/User/Plugin/Samba.php

https://github.com/pschuele/Tine-2.0-Open-Source-Groupware-and-CRM
PHP | 271 lines | 167 code | 31 blank | 73 comment | 28 complexity | 85a45df29667908bc8b3459274af83a6 MD5 | raw file
  1. <?php
  2. /**
  3. * Tine 2.0
  4. *
  5. * @package Tinebase
  6. * @subpackage User
  7. * @license http://www.gnu.org/licenses/agpl.html AGPL Version 3
  8. * @copyright Copyright (c) 2010 Metaways Infosystems GmbH (http://www.metaways.de)
  9. * @author Lars Kneschke <l.kneschke@metaways.de>
  10. * @version $Id$
  11. */
  12. /**
  13. * plugin to handle sambaSAM ldap attributes
  14. *
  15. * @package Tinebase
  16. * @subpackage User
  17. */
  18. class Tinebase_User_Plugin_Samba extends Tinebase_User_Plugin_LdapAbstract
  19. {
  20. /**
  21. * mapping of ldap attributes to class properties
  22. *
  23. * @var array
  24. */
  25. protected $_propertyMapping = array(
  26. 'sid' => 'sambasid',
  27. 'primaryGroupSID' => 'sambaprimarygroupsid',
  28. 'acctFlags' => 'sambaacctflags',
  29. 'homeDrive' => 'sambahomedrive',
  30. 'homePath' => 'sambahomepath',
  31. 'profilePath' => 'sambaprofilepath',
  32. 'logonScript' => 'sambalogonscript',
  33. 'logonTime' => 'sambalogontime',
  34. 'logoffTime' => 'sambalogofftime',
  35. 'kickoffTime' => 'sambakickofftime',
  36. 'pwdLastSet' => 'sambapwdlastset',
  37. 'pwdCanChange' => 'sambapwdcanchange',
  38. 'pwdMustChange' => 'sambapwdmustchange',
  39. );
  40. /**
  41. * objectclasses required for users
  42. *
  43. * @var array
  44. */
  45. protected $_requiredObjectClass = array(
  46. 'sambaSamAccount'
  47. );
  48. /**
  49. * the constructor
  50. *
  51. * @param array $options options used in connecting, binding, etc.
  52. */
  53. public function __construct(array $_options = array())
  54. {
  55. parent::__construct($_options);
  56. if (empty($this->_options['sid'])) {
  57. throw new Exception('you need to configure the sid of the samba installation');
  58. }
  59. }
  60. /**
  61. * inspect set expiry date
  62. *
  63. * @param Tinebase_DateTime $_expiryDate the expirydate
  64. * @param array $_ldapData the data to be written to ldap
  65. */
  66. public function inspectExpiryDate($_expiryDate, array &$_ldapData)
  67. {
  68. if ($_expiryDate instanceof Tinebase_DateTime) {
  69. // seconds since Jan 1, 1970
  70. $_ldapData['sambakickofftime'] = $_expiryDate->getTimestamp();
  71. } else {
  72. $_ldapData['sambakickofftime'] = array();
  73. }
  74. }
  75. /**
  76. * inspect setStatus
  77. *
  78. * @param string $_status the status
  79. * @param array $_ldapData the data to be written to ldap
  80. */
  81. public function inspectStatus($_status, array &$_ldapData)
  82. {
  83. $acctFlags = '[U ]';
  84. $acctFlags[2] = $_status == 'disabled' ? 'D' : ' ';
  85. $_ldapData['sambaacctflags'] = $acctFlags;
  86. }
  87. /**
  88. * inspect set password
  89. *
  90. * @param string $_userId
  91. * @param string $_password
  92. * @param boolean $_encrypt
  93. * @param boolean $_mustChange
  94. * @param array $_ldapData the data to be written to ldap
  95. */
  96. public function inspectSetPassword($_userId, $_password, $_encrypt, $_mustChange, array &$_ldapData)
  97. {
  98. if ($_encrypt !== true) {
  99. Tinebase_Core::getLogger()->crit(__METHOD__ . '::' . __LINE__ . ' can not transform crypted password into nt/lm samba password. Make sure to reset password for user ' . $_userId);
  100. } else {
  101. $_ldapData['sambantpassword'] = Tinebase_User_Abstract::encryptPassword($_password, Tinebase_User_Abstract::ENCRYPT_NTPASSWORD);
  102. $_ldapData['sambalmpassword'] = array();
  103. if ($_mustChange === true) {
  104. $_ldapData['sambapwdmustchange'] = '1';
  105. $_ldapData['sambapwdcanchange'] = '1';
  106. $_ldapData['sambapwdlastset'] = array();
  107. } else if ($_mustChange === false) {
  108. $_ldapData['sambapwdmustchange'] = '2147483647';
  109. $_ldapData['sambapwdcanchange'] = '1';
  110. $_ldapData['sambapwdlastset'] = Tinebase_DateTime::now()->getTimestamp();
  111. } else if ($_mustChange === null &&
  112. $_userId instanceof Tinebase_Model_FullUser &&
  113. isset($_userId->sambaSAM) &&
  114. isset($_userId->sambaSAM->pwdMustChange) &&
  115. isset($_userId->sambaSAM->pwdCanChange)) {
  116. $_ldapData['sambapwdmustchange'] = $_userId->sambaSAM->pwdMustChange->getTimestamp();
  117. $_ldapData['sambapwdcanchange'] = $_userId->sambaSAM->pwdCanChange->getTimestamp();
  118. $_ldapData['sambapwdlastset'] = array();
  119. }
  120. }
  121. }
  122. /**
  123. * converts raw ldap data to sambasam object
  124. *
  125. * @param Tinebase_Model_User $_user
  126. * @param array $_ldapEntry
  127. */
  128. protected function _ldap2User(Tinebase_Model_User $_user, array &$_ldapEntry)
  129. {
  130. $accountArray = array();
  131. foreach ($_ldapEntry as $key => $value) {
  132. if (is_int($key)) {
  133. continue;
  134. }
  135. $keyMapping = array_search($key, $this->_propertyMapping);
  136. if ($keyMapping !== FALSE) {
  137. switch($keyMapping) {
  138. case 'pwdLastSet':
  139. case 'logonTime':
  140. case 'logoffTime':
  141. case 'kickoffTime':
  142. case 'pwdCanChange':
  143. case 'pwdMustChange':
  144. $accountArray[$keyMapping] = new Tinebase_DateTime($value[0]);
  145. break;
  146. default:
  147. $accountArray[$keyMapping] = $value[0];
  148. break;
  149. }
  150. }
  151. }
  152. $_user->sambaSAM = new Tinebase_Model_SAMUser($accountArray);
  153. }
  154. /**
  155. * return sid of group
  156. *
  157. * @param string $_groupId
  158. * @return string the sid of the group
  159. */
  160. protected function _getGroupSID($_groupId)
  161. {
  162. $ldapOptions = Tinebase_User::getBackendConfiguration();
  163. $filter = Zend_Ldap_Filter::equals(
  164. $ldapOptions['groupUUIDAttribute'], Zend_Ldap::filterEscape($_groupId)
  165. );
  166. $groups = $this->_ldap->search(
  167. $filter,
  168. $ldapOptions['groupsDn'],
  169. Zend_Ldap::SEARCH_SCOPE_SUB,
  170. array('sambasid')
  171. );
  172. if (count($groups) == 0) {
  173. throw new Tinebase_Exception_NotFound('Group not found! Filter: ' . $filter->toString());
  174. }
  175. $group = $groups->getFirst();
  176. if (empty($group['sambasid'][0])) {
  177. throw new Tinebase_Exception_NotFound('Group has no sambaSID');
  178. }
  179. return $group['sambasid'][0];
  180. }
  181. /**
  182. * (non-PHPdoc)
  183. * @see Tinebase_User_Plugin_LdapAbstract::_user2ldap()
  184. */
  185. protected function _user2ldap(Tinebase_Model_FullUser $_user, array &$_ldapData, array &$_ldapEntry = array())
  186. {
  187. $this->inspectExpiryDate(isset($_user->accountExpires) ? $_user->accountExpires : null, $_ldapData);
  188. if ($_user->sambaSAM instanceof Tinebase_Model_SAMUser) {
  189. foreach ($_user->sambaSAM as $key => $value) {
  190. if (array_key_exists($key, $this->_propertyMapping)) {
  191. switch ($key) {
  192. case 'pwdLastSet':
  193. case 'logonTime':
  194. case 'logoffTime':
  195. case 'kickoffTime':
  196. case 'sid':
  197. case 'primaryGroupSID':
  198. case 'acctFlags':
  199. // do nothing
  200. break;
  201. case 'pwdCanChange':
  202. case 'pwdMustChange':
  203. if ($value instanceof Tinebase_DateTime) {
  204. $_ldapData[$this->_propertyMapping[$key]] = $value->getTimestamp();
  205. } else {
  206. $_ldapData[$this->_propertyMapping[$key]] = array();
  207. }
  208. break;
  209. default:
  210. $_ldapData[$this->_propertyMapping[$key]] = $value;
  211. break;
  212. }
  213. }
  214. }
  215. }
  216. if (empty($_ldapEntry['sambasid'])) {
  217. $uidNumer = isset($_ldapData['uidnumber']) ? $_ldapData['uidnumber'] : $_ldapEntry['uidnumber'][0];
  218. $_ldapData['sambasid'] = $this->_options['sid'] . '-' . (2 * $uidNumer + 1000);
  219. }
  220. $_ldapData['sambaacctflags'] = !empty($_ldapEntry['sambaacctflags']) ? $_ldapEntry['sambaacctflags'][0] : '[U ]';
  221. if ($_user->sambaSAM instanceof Tinebase_Model_SAMUser) {
  222. $_ldapData['sambaacctflags'][1] = !empty($_user->sambaSAM->acctFlags) ? $_user->sambaSAM->acctFlags[1] : 'U';
  223. }
  224. $_ldapData['sambaacctflags'][2] = ($_user->accountStatus != 'enabled') ? 'D' : ' ';
  225. try {
  226. $_ldapData['sambaprimarygroupsid'] = $this->_getGroupSID($_user->accountPrimaryGroup);
  227. } catch (Tinebase_Exception_NotFound $tenf) {
  228. $_ldapData['sambaprimarygroupsid'] = array();
  229. }
  230. // check if user has all required object classes. This is needed
  231. // when updating users which where created using different requirements
  232. foreach ($this->_requiredObjectClass as $className) {
  233. if (! in_array($className, $_ldapData['objectclass'])) {
  234. // merge all required classes at once
  235. $_ldapData['objectclass'] = array_unique(array_merge($_ldapData['objectclass'], $this->_requiredObjectClass));
  236. break;
  237. }
  238. }
  239. }
  240. }