| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832 |
- <?php
- Lib::loadClass('UserStorageBase');
- Lib::loadClass('ObjectUserLdap');
- Lib::loadClass('ObjectGroupLdap');
- Lib::loadClass('UsersLdapHelper');
- Lib::loadClass('LDAP');
- /**
- * Test remove user:
- * $ dscl /Local/Default -list /Groups GroupMembership | grep test13
- * ... for all groups:
- * $ dscl -u diradmin -p /Local/Default -delete /Groups/workgroup GroupMembership test13
- * $ dscl /LDAPv3/127.0.0.1 -list /Groups GroupMembership | grep test13
- * ... for all groups:
- * $ dscl -u diradmin -p /LDAPv3/127.0.0.1 -delete /Groups/workgroup GroupMembership test13
- * $ dscl -u diradmin -p /Local/Default -delete /Users/test13
- */
- class UserStorageMacOSX extends UserStorageBase {
- private $_rootUser;
- private $_rootPass;
- private $_host;
- private $_ldapRoot;
- public function __construct($rootUser, $rootPass, $host) {
- $this->_rootUser = $rootUser;
- $this->_rootPass = $rootPass;
- $this->_host = $host;
- }
- /**
- * @return ObjectUserLdap
- */
- public function getUser($userName) {
- $usrLdap = UsersLdapHelper::getUser($userName, true);
- if (empty($usrLdap[0])) return null;
- DBG::_('DBG_SU', true, 'usrLdap', $usrLdap[0], __CLASS__, __FUNCTION__, __LINE__);
- $user = $this->_buildUserFromLdap($usrLdap[0]);
- return $user;
- }
- private function _buildUserFromLdap($usrLdap) {
- $user = new ObjectUserLdap($this);
- $user->primaryKey = V::get('uidNumber', '', $usrLdap);
- $user->login = V::get('uid', '', $usrLdap);
- $user->password = '';
- $user->name = V::get('cn', '', $usrLdap);
- $user->email = V::get('mail', '', $usrLdap);
- $user->phone = V::get('telephoneNumber', '', $usrLdap);
- $user->homeEmail = V::get('carLicense', '', $usrLdap);
- $user->homePhone = V::get('homePhone', '', $usrLdap);
- $user->employeeType = V::get('employeeType', '', $usrLdap);
- return $user;
- }
- /**
- * @return ObjectGroupLdap $group
- */
- public function getGroup($groupID) {
- return $this->_getGroup($groupID, $fetchNested = true);
- }
- private function _getGroup($groupID, $fetchNested = false) {
- if ($groupID <= 0) return false;
- $group = null;
- $groups = UsersLdapHelper::getGroupsByID($groupID);
- if (count($groups) == 1) {
- $group = reset($groups);
- if(V::get('DBG_SU', 0, $_GET, 'int') > 2){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">groupLdap (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($group);echo'</pre>';}
- $group = $this->_buildGroupFromLdap($group, $fetchNested);
- if(V::get('DBG_SU', 0, $_GET, 'int') > 2){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">group (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($group);echo'</pre>';}
- } else if (count($groups) > 1) {
- if(V::get('DBG_SU', 0, $_GET, 'int') > 0){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">'."Too much groups in ldap by ID {$groupID}".' (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($groups);echo'</pre>';}
- trigger_error("Too much groups in ldap by ID {$groupID}", E_USER_WARNING);
- }
- return $group;
- }
- public function getParentGroups(ObjectGroup $group) {
- $parentGroups = array();
- $parentGroupsLdap = UsersLdapHelper::getParentGroupsByAppleUID($group->getLdapUID());
- foreach ($parentGroupsLdap as $groupLdap) {
- $group = $this->_buildGroupFromLdap($groupLdap);
- if ($group->zasobID > 0) {
- $parentGroups[$group->zasobID] = $group;
- }
- }
- return $parentGroups;
- }
- /**
- * @return bool
- */
- public function isDisabled($usr) {
- if (!$usr) throw new Exception("Błąd podczas sprawdzania statusu blokady - nie podano użytkownika!");
- if (null === $usr->isDisabled) {
- $allGroups = $this->_fetchAllUserGroups($usr->login);
- $usr->isDisabled = in_array('com.apple.access_disabled', $allGroups);
- DBG::_('DBG_SU', '>1', "usr->isDisabled(" . (($usr->isDisabled)? 'true' : 'false') . ") ", null, __CLASS__, __FUNCTION__, __LINE__);
- }
- return $usr->isDisabled;
- }
- /**
- * @return bool
- */
- public function setDisabled($usrLogin, $isDisabled) {
- // pwpolicy -a diradmin -u t1 -disableuser
- // pwpolicy -a diradmin -u t1 -enableuser
- if (empty($usrLogin) || null === $isDisabled) {
- return false;
- }
- $cmdDisabled = ($isDisabled)? ' -disableuser' : ' -enableuser';
- $cmd = "pwpolicy -a {$this->_rootUser} -p {$this->_rootPass} -u {$usrLogin} {$cmdDisabled} 2>&1 ";
- $cmdOut = null; $cmdRet = null;
- exec($cmd, $cmdOut, $cmdRet);
- DBG::_('DBG_SU', '>1', "cmd(" . str_replace($this->_rootPass, '***', $cmd) . ") ret({$cmdRet}) ", $cmdOut, __CLASS__, __FUNCTION__, __LINE__);
- if ($cmdRet !== 0) {
- return false;
- }
- return true;
- }
- /**
- * @param $usr - user object @see UserStorageBase::getUser()
- * $usr->employeeType: Pracownik, Kandydat, Partner, Anonymous
- * Pracownik - all access
- * Kandydat - no access
- * Partner - access: smb/afp, TODO: calendar?, addressbook?
- * Anonymous - no access
- */
- public function createUser($usr) {
- DBG::_('DBG_SU', '>1', 'usr', $usr, __CLASS__, __FUNCTION__, __LINE__);
- $cmdDsclAuth = "dscl -u {$this->_rootUser} -P {$this->_rootPass} /LDAPv3/127.0.0.1 ";
- $login = $this->_cleanUid($usr->login);
- $name = $this->_cleanText($usr->name);
- $type = $usr->employeeType;
- $email = $usr->email;
- $pass = $usr->password;
- $uniqueID = 0;
- // test user login and pass by searching for $uniqueID for new user
- $cmd = "{$cmdDsclAuth} -list /Users > /dev/null && {$cmdDsclAuth} -list /Users UniqueID|awk '{print \$2}'|sort -n|tail -1 ";
- $cmdOut = null; $cmdRet = null;
- exec($cmd, $cmdOut, $cmdRet);
- if ($cmdRet == 0 && !empty($cmdOut[0])) {
- $uniqueID = intval($cmdOut[0]);
- if ($uniqueID > 0) {
- $uniqueID += 1;
- }
- }
- if ($uniqueID <= 0) {
- throw new Exception("Error: dscl auth - check login and password in ldap config");
- }
- if (empty($name)) {
- $name = $login;
- } else {
- // TODO: replace bad signs str_replace($_SESSION['CONFIG']['BAD_FILE_SIGNS_LETTERS'],$_SESSION['CONFIG']['OK_FILE_SIGNS_LETTERS'],$ADM_NAME)
- }
- if (empty($pass)) {
- $pass = $login;
- }
- $cmds = array();
- //$cmds[] = "{$cmdDsclAuth} -create /Users/{$login} HomeDirectory \"<home_dir><url>afp://{$this->_host}/Users</url><path>{$login}</path></home_dir>\" ";
- //$cmds[] = "{$cmdDsclAuth} -create /Users/{$login} NFSHomeDirectory /Network/Servers/{$this->_host}/Users/{$login} ";
- $cmds[] = "{$cmdDsclAuth} -create /Users/{$login} NFSHomeDirectory /Users/{$login} ";
- $cmds[] = "{$cmdDsclAuth} -create /Users/{$login} UserShell /bin/bash ";// TODO: bash?
- $cmds[] = "{$cmdDsclAuth} -create /Users/{$login} UniqueID {$uniqueID} ";
- $cmds[] = "{$cmdDsclAuth} -create /Users/{$login} PrimaryGroupID 20 ";// TODO: 20 maja domyslnie inne konta?
- $cmds[] = "{$cmdDsclAuth} -create /Users/{$login} RealName \"{$name}\" ";
- if (!empty($email)) $cmds[] = "{$cmdDsclAuth} -create /Users/{$login} EMailAddress {$email} ";
- $cmds[] = "{$cmdDsclAuth} -passwd /Users/{$login} \"{$pass}\" ";
- $cmds[] = "sudo /usr/sbin/createhomedir -c -u {$login} 2>&1 ";// TODO:INSTALATOR: add to sudoers _www ALL = NOPASSWD: /usr/sbin/createhomedir
- foreach ($cmds as $cmd) {
- $cmdOut = null; $cmdRet = null;
- exec($cmd, $cmdOut, $cmdRet);
- if ($cmdRet != 0) {
- DBG::_('DBG_SU', '>1', "cmd failed: " . str_replace($cmdDsclAuth, "dscl __auth__ ", $cmd), $cmdOut, __CLASS__, __FUNCTION__, __LINE__);
- throw new Exception("Wystąpił błąd podczas tworzenia użytwkonika '{$usrLogin}' w bazie Ldap");
- }
- }
- }
- private function _getAdminLdap() {
- if (!$this->_ldapRoot) {
- $this->_ldapRoot = LDAP::getInstance();
- if (!$this->_ldapRoot->bindDiradmin($errorMsg)) {
- // $errorMsg?
- $this->setError(1, "cant bind as diradmin", '(' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . ')');
- return null;
- }
- }
- return $this->_ldapRoot;
- }
- public function updateUser($userName, $updateData) {
- if (empty($updateData)) return true;
- foreach ($updateData as $fldName => $val) {
- $val = trim($val);
- switch ($fldName) {
- case 'email':
- $ldap = $this->_getAdminLdap();
- if ($ldap) {
- $attr = array();
- $attr['mail'] = $val;
- $ldap->mod_replace($userName, $attr);
- }
- break;
- case 'name':
- $ldap = $this->_getAdminLdap();
- if ($ldap) {
- $attr = array();
- $attr['cn'] = $val;
- $ldap->mod_replace($userName, $attr);
- }
- break;
- case 'phone':
- $ldap = $this->_getAdminLdap();
- if ($ldap) {
- $attr = array();
- $attr['telephoneNumber'] = $val;
- $ldap->mod_replace($userName, $attr);
- }
- break;
- case 'employeeType':
- $ldap = $this->_getAdminLdap();
- if ($ldap) {
- $attr = array();
- $attr['employeeType'] = $val;
- $ldap->mod_replace($userName, $attr);
- }
- break;
- case 'password':
- if (!empty($val) && !$this->changePassword($userName, $val)) {
- $this->setError(1, "Nie udało się zmienić hasła dla usera '{$userName}'", '(' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . ')');
- }
- break;
- case 'homeEmail':
- $ldap = $this->_getAdminLdap();
- if ($ldap) {
- $attr = array();
- $attr['carLicense'] = $val;
- if (!$ldap->mod_replace($userName, $attr)) {
- if (!$ldap->mod_add($userName, $attr)) {
- //$this->setError(1, "TODO: update homeEmail failed " . $ldap->error(), '(' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . ')');
- }
- }
- }
- break;
- default:
- $this->setError(1, "TODO: update user {$userName} field {$fldName} to value '{$val}'", '(' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . ')');
- }
- }
- if ($this->hasErrors()) {
- $this->setError(1, "Nie udało się zaktualizować danych usera '{$userName}'", '(' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . ')');
- return false;
- }
- return true;
- }
- public function updateGroup($group, $updateData) {
- if (!$group) return false;
- if (empty($updateData)) return true;
- foreach ($updateData as $fldName => $val) {
- switch ($fldName) {
- case 'realName':
- $ldap = $this->_getAdminLdap();
- if ($ldap) {
- $attr = array();
- $attr['apple-group-realname'] = $val;
- $ldap->groupAttrUpdate($group->primaryKey, $attr);
- }
- break;
- default:
- $this->setError(1, "Błąd podczas aktulizacji grupy '{$group->primaryKey}' - pole '{$fldName}' watość '{$val}'", '#L' . __LINE__);
- }
- }
- return true;
- }
- private function _getGroupIdFromUid($groupUid) {
- if (empty($groupUid)) return null;
- if (!is_numeric(substr($groupUid, 0, 1))) return null;
- $tmp = str_replace(array('-', '_'), '_', $groupUid);
- $tmp = explode('_', $tmp);
- $tmp = reset($tmp);
- if (!empty($tmp) && is_numeric($tmp)) {
- return $tmp;
- }
- return null;
- }
- /**
- * User group list by id.
- *
- * @param bool $fetchNested - contain all groups below connected groups and group PODMIOT from above.
- *
- * @return array with group objects @see getGroup
- */
- public function getUserGroups($usrLogin, $fetchNested = false) {
- $groups = array();
- $groupsNetwork = $this->_getUserGroupsNetwork($usrLogin);
- $groupsLocal = $this->_getUserGroupsLocal($usrLogin);
- foreach ($groupsLocal as $kGroupUid => $vGroup) {
- $groups[$kGroupUid] = $vGroup;
- }
- foreach ($groupsNetwork as $kGroupUid => $vGroupNetwork) {
- if ($vGroupNetwork->primaryKey == 'workgroup') {
- $groups[$vGroupNetwork->primaryKey] = $vGroupNetwork;
- }
- else if ($vGroupNetwork->zasobID > 0) {
- $groups[$vGroupNetwork->zasobID] = $vGroupNetwork;
- }
- }
- DBG::_('DBG_SU', '>2', "groupsNetwork", array_keys($groupsNetwork), __CLASS__, __FUNCTION__, __LINE__);
- DBG::_('DBG_SU', '>2', "groupsLocal", array_keys($groupsLocal), __CLASS__, __FUNCTION__, __LINE__);
- return $groups;
- }
- /**
- * Build network group object.
- *
- * @param object $groupDB {ID, DESC} @see _getUserGroupsAll
- * @return object $group @see getGroup
- *
- * Example: _buildGroupFromLdap($groupLdap) => {@see getGroup}
- */
- private function _buildGroupFromLdap($groupLdap, $fetchNested = false) {
- $group = new ObjectGroupLdap('MacOSX');
- $group->primaryKey = $groupLdap->cn;
- $group->realName = V::get('realName', '', $groupLdap);
- $group->zasobID = $this->_getGroupIdFromUid($groupLdap->cn);
- $group->type = 'unknown';// TODO: try to fetch from name or from ldap attribute
- if ($groupLdap->cn == 'workgroup') $group->type = 'network';
- if ($fetchNested && !empty($groupLdap->nestedGroups)) {
- $group->nestedGroups = $this->_fetchNestedGroupsByAppleUids($groupLdap->nestedGroups);
- }
- $group->setLdapUID($groupLdap->appleUID);
- return $group;
- }
- public function getGroupsByUserUid($usrLogin) {
- $groups = array();
- $rawUsrLdap = UsersLdapHelper::getUser($usrLogin, true);
- $rawUsrLdap = (!empty($rawUsrLdap))? $rawUsrLdap[0] : null;
- if (!$rawUsrLdap) return $groups;
- $usrAppleUid = V::get('apple-generateduid', '', $rawUsrLdap);
- DBG::_('DBG_SU', '>0', "CleanupAppleMemberUidTodoList user apple-generateduid({$usrAppleUid})", $rawUsrLdap, __CLASS__, __FUNCTION__, __LINE__);
- if (empty($usrAppleUid)) return $groups;
- $groupsLdap = UsersLdapHelper::getUserGroupsByAppleUid($usrAppleUid, 0);
- foreach ($groupsLdap as $groupLdap) {
- $group = $this->_buildGroupFromLdap($groupLdap);
- if ($group->zasobID > 0) {
- $groups[$group->zasobID] = $group;
- }
- }
- return $groups;
- }
- private function _fetchNestedGroupsByAppleUids($appleUids) {
- $groups = array();
- if (!is_array($appleUids)) $appleUids = array($appleUids);
- $groupsLdap = UsersLdapHelper::getGroupsByAppleUids($appleUids);
- foreach ($groupsLdap as $vGroupLdap) {
- $group = $this->_buildGroupFromLdap($vGroupLdap, $fetchNested = false);
- if ($group && $group->zasobID > 0) {
- $groups[$group->zasobID] = $group;
- }
- }
- return $groups;
- }
- /**
- * @param string $usrLogin - user login
- * @return array of group objects @see getGroup
- */
- private function _getUserGroupsNetwork($usrLogin) {
- $groups = array();
- $groupsNetwork = UsersLdapHelper::getUserGroups($usrLogin, 0);
- foreach ($groupsNetwork as $vGroupNetwork) {
- $groups[$vGroupNetwork->cn] = $this->_buildGroupFromLdap($vGroupNetwork);
- }
- return $groups;
- }
- /**
- * @param string $usrLogin - user login
- * @return array of group objects @see getGroup
- */
- private function _getUserGroupsLocal($usrLogin) {
- $groups = array();
- $allGroups = $this->_fetchAllUserGroups($usrLogin);
- foreach ($allGroups as $groupName) {
- if ($this->_isGroupLocal($groupName)) {
- $groups[$groupName] = $this->_buildGroupLocal($groupName);
- }
- }
- DBG::_('DBG_SU', '>1', "User '{$usrLogin}' GroupsLocal:", $groups, __CLASS__, __FUNCTION__, __LINE__);
- return $groups;
- }
- private function _fetchAllUserGroups($usrLogin) {
- $groups = array();
- $cmd = "groups {$usrLogin}";
- $cmdOut = null; $cmdRet = null;
- exec($cmd, $cmdOut, $cmdRet);
- if ($cmdRet == 0 && !empty($cmdOut[0])) {
- $groupsCmd = explode(' ', $cmdOut[0]);
- foreach ($groupsCmd as $groupName) {
- if (!empty($groupName)) {
- $groups[] = $groupName;
- }
- }
- }
- DBG::_('DBG_SU', '>1', "User '{$usrLogin}' all groups:", $groups, __CLASS__, __FUNCTION__, __LINE__);
- return $groups;
- }
- public function getUserGroupsWithNested($usrLogin) {// TODO: NOT USED
- $groups = array();
- $groupsAll = array();
- $cmd = "groups {$usrLogin}";
- $cmdOut = null; $cmdRet = null;
- exec($cmd, $cmdOut, $cmdRet);
- if ($cmdRet == 0 && !empty($cmdOut[0])) {
- $pominGrupy = array('staff','everyone','netaccounts');
- $groupsCmd = explode(' ', $cmdOut[0]);
- foreach ($groupsCmd as $group) {
- $groupsAll[] = $group;
- $groupID = $this->_getGroupIdFromUid($group);
- if (!empty($groupID)) {
- $groups[$groupID] = $group;
- }
- else if ('workgroup' == $group) {
- $groups[$group] = $group;
- }
- else if (substr($group, 0, strlen('com.apple.access_')) == 'com.apple.access_') {
- $groups[$group] = $group;
- }
- }
- }
- if (V::get('DBG_SU', 0, $_GET, 'int') > 1) {
- echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">groupsAll (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($groupsAll);echo'</pre>';
- echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">groups (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($groups);echo'</pre>';
- }
- return $groups;
- }
- private function _groupNameRemoveID($groupName) {
- if (substr($groupName, 0, 1) == '[' && strpos($groupName, ']')) {
- $groupName = substr($groupName, strpos($groupName, ']') + 1);
- $groupName = trim($groupName);
- }
- return $groupName;
- }
- private function _generateGroupName($id, $groupName) {
- $groupNameShort = $groupName;
- $groupNameShort = $this->_groupNameRemoveID($groupNameShort);
- // TODO: polish chars - replace to ascii?
- $groupNameShort = preg_replace('/[^a-zA-Z0-9_-]+/', '_', $groupNameShort);
- // TODO: skrócić nazwę bo nie widać w aplikacji Server, np.
- // RealName: [5] Typowe_stanowisko_obs_uguj_ce_Obieg_Dokument_w_do_implementacji_po_instalacji_systemu
- // w apliakcji Server pokauje tylko "[5] ", tak samo w edycji
- return "[{$id}] {$groupNameShort}";
- }
- private function _generateGroupUid($id, $groupName) {
- $groupNameShort = $groupName;
- $groupNameShort = $this->_groupNameRemoveID($groupNameShort);
- $groupNameShort = str_replace(' ', '_', $groupNameShort);
- $groupNameShort = preg_replace('/[^a-zA-Z0-9_-]+/', '_', $groupNameShort);
- if (strlen($groupNameShort) > 30) {
- $groupNameShort = substr($groupNameShort, 0, 30);
- }
- return "{$id}_{$groupNameShort}";
- }
- /**
- * Create group.
- *
- * @param object $group @see getGroup
- * @return bool
- *
- * @require $group->zasobID - Allowed only network group based on Zasob.
- */
- public function createGroup(ObjectGroup $group) {
- // TEST: $ dscl /LDAPv3/127.0.0.1 -list /Groups PrimaryGroupID
- if ($group->zasobID <= 0) {
- throw new Exception("Nie udało się utworzyć grupy sieciowej '{$group->primaryKey}' '{$group->realName}' - brak numery zasobu");
- }
- $groupName = $this->_generateGroupName($group->zasobID, $group->realName);
- $groupUidGenerated = $this->_generateGroupUid($group->zasobID, $group->realName);
- /*
- * dseditgroup -o create -n /LDAPv3/ldap.company.com -u {$this->_rootUser} -P {$this->_rootPass} -r "Extra Group" -c "a nice comment" -k "some keyword" extragroup
- * The group extragroup is created from the node /LDAPv3/ldap.company.com with the realname, comment,
- * timetolive (instead of default of 14400 = 4 hours), and keyword atttribute values given above if the user
- * myusername has supplied a correct password and has write access.
- *
- * -r realname
- * This is a simple text string.
- *
- * -t recordtype
- * The type of the record to be added to or deleted from the group specified by groupname. Valid values are user, computer, group, or computergroup.
- *
- */
- $cmd = "dseditgroup -o create -n /LDAPv3/127.0.0.1 -u {$this->_rootUser} -P {$this->_rootPass} -r \"{$groupName}\" {$groupUidGenerated}";
- $cmdOut = null; $cmdRet = null;
- exec($cmd, $cmdOut, $cmdRet);
- DBG::_('DBG_SU', '>1', "create group cmd(" . str_replace($this->_rootPass, '***', $cmd) . ") ret({$cmdRet})", $cmdOut, __CLASS__, __FUNCTION__, __LINE__);
- if ($cmdRet !== 0) {
- throw new Exception("Nie udało się utworzyć grupy sieciowej '{$group->primaryKey}' '{$group->realName}'");
- }
- //$command8 = "dscl -u {$user} -P {$pass} /LDAPv3/127.0.0.1 -append /Groups/{$groupUid} GroupMembership {$ACCOUNT} ";
- //$command8 = "dscl -u {$user} -P {$pass} /LDAPv3/127.0.0.1 -delete /Groups/{$groupUid} GroupMembership {$ACCOUNT} ";
- //$command1 = "dscl -u {$user} -P {$pass} /LDAPv3/127.0.0.1 -create /Groups/{$groupUid} PrimaryGroupID {$PrimaryGroupID} ";
- //$command2 = "dscl -u {$user} -P {$pass} /LDAPv3/127.0.0.1 -create /Groups/{$groupUid} RealName \"{$groupName}\" ";
- }
- private function _isGroupLocal($groupUid) {
- $localGroups = array();
- $localGroups[] = 'com.apple.access_mail';
- $localGroups[] = 'com.apple.access_addressbook';
- $localGroups[] = 'com.apple.access_calendar';
- $localGroups[] = 'com.apple.access_smb';
- $localGroups[] = 'com.apple.access_afp';
- $localGroups[] = 'com.apple.access_vpn';
- $localGroups[] = 'com.apple.access_chat';
- //$localGroups[] = 'workgroup'; - Network Group
- return in_array($groupUid, $localGroups);
- }
- /**
- * Add local group member.
- *
- * @param string $usrLogin - user login
- * @param object $group - @see getGroup
- * @return bool
- *
- * @require sudoers dla _www
- *
- * cat /etc/sudoers |grep "'.$ADMIN_USERNAME.' ALL = NOPASSWD: /usr/bin/su" || echo "'.$ADMIN_USERNAME.' ALL = NOPASSWD: /usr/bin/su " >> /etc/sudoers;
- * cat /etc/sudoers |grep "'.$ADMIN_USERNAME.' ALL = NOPASSWD: /usr/bin/su"
- * cat /etc/sudoers |grep "_www ALL = NOPASSWD: /Applications/Server.app/Contents/ServerRoot/usr/sbin/calendarserver_manage_principals" || echo "_www ALL = NOPASSWD: /Applications/Server.app/Contents/ServerRoot/usr/sbin/calendarserver_manage_principals " >> /etc/sudoers;
- * cat /etc/sudoers |grep "_www ALL = NOPASSWD: /Applications/Server.app/Contents/ServerRoot/usr/sbin/calendarserver_manage_principals"';
- * cat /etc/sudoers |grep "_www ALL = NOPASSWD: /usr/bin/dscl" || echo "_www ALL = NOPASSWD: /usr/bin/dscl " >> /etc/sudoers;
- * cat /etc/sudoers |grep "_www ALL = NOPASSWD: /usr/bin/dscl";
- * cat /etc/sudoers |grep "_www ALL = NOPASSWD: /usr/bin/pwpolicy" || echo "_www ALL = NOPASSWD: /usr/bin/pwpolicy" >> /etc/sudoers;
- * cat /etc/sudoers |grep "_www ALL = NOPASSWD: /usr/bin/pwpolicy";
- * cat /etc/sudoers |grep "_www ALL = NOPASSWD: /usr/sbin/createhomedir" || echo "_www ALL = NOPASSWD: /usr/sbin/createhomedir" >> /etc/sudoers;
- * cat /etc/sudoers |grep "_www ALL = NOPASSWD: /usr/sbin/createhomedir";
- *
- * cat /etc/sudoers |grep "_www ALL = NOPASSWD: /usr/sbin/dseditgroup" || echo "_www ALL = NOPASSWD: /usr/sbin/dseditgroup" >> /etc/sudoers;
- * cat /etc/sudoers |grep "_www ALL = NOPASSWD: /usr/sbin/dseditgroup";
- */
- private function _addUserGroupLocal($usrLogin, $group) {
- if (!$group || empty($group->primaryKey) || empty($usrLogin)) return false;
- $groupUid = $group->primaryKey;
- $cmd = "sudo dscl /Local/Default -append /Groups/{$groupUid} GroupMembership {$usrLogin} ";
- $cmdOut = null; $cmdRet = null;
- exec($cmd, $cmdOut, $cmdRet);
- if ($cmdRet != 0) {
- throw new Exception("Nie udało się dodać usera '{$usrLogin}' do grupy lokalnej '{$groupUid}'");
- }
- }
- /**
- * Remove local group member.
- *
- * @param string $usrLogin - user login
- * @param object $group - @see getGroup
- * @return bool
- */
- private function _removeUserGroupLocal($usrLogin, $group) {
- if (!$group || empty($group->primaryKey) || empty($usrLogin)) return false;
- $groupUid = $group->primaryKey;
- //$cmd = "sudo dscl /Local/Default -delete /Groups/{$groupUid} GroupMembership {$usrLogin} 2>&1 ";
- //$cmd = "dseditgroup -o edit -n /Local/Default -u diradmin -p ... -d username -t user {$groupUid} ";
- $cmd = "sudo dseditgroup -o edit -n /Local/Default -d {$usrLogin} -t user {$groupUid} 2>&1 ";
- // The group extragroup from the node /LDAPv3/ldap.company.com will have the username deleted if the correct
- // password is presented interactively for the user myusername which also need to have write access.
- // -t recordtype type of the record to add or delete
- // -d recordname name of the record to delete
- $cmdOut = null; $cmdRet = null;
- exec($cmd, $cmdOut, $cmdRet);
- DBG::_('DBG_SU', '>1', "cmd({$cmd}) ret({$cmdRet})", $cmdOut, __CLASS__, __FUNCTION__, __LINE__);
- if ($cmdRet != 0) {
- throw new Exception("Nie udało się dodać usera '{$usrLogin}' z grupy lokalnej '{$groupUid}'");
- }
- }
- public function findGroupUidDscl($groupUid) {// not used @see findGroupUid
- $groupRealUid = null;
- $cmd = "dscl /LDAPv3/127.0.0.1 -list /Groups | grep '^{$groupUid}' ";
- $cmdOut = null; $cmdRet = null;
- exec($cmd, $cmdOut, $cmdRet);
- if ($cmdRet != 0) {
- $this->setError(1, "cmd failed - search for group by uid", '(' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . ')');
- return false;
- }
- if (!empty($cmdOut)) {
- foreach ($cmdOut as $vGroupUid) {
- $vGroupID = $this->_getGroupIdFromUid($vGroupUid);
- if (!empty($vGroupID) && $vGroupID == $groupUid) {
- $groupRealUid = $vGroupUid;
- break;
- }
- }
- }
- return $groupRealUid;
- }
- public function findGroupUidLdap($groupUid) {
- $groupRealUid = null;
- $groups = UsersLdapHelper::getGroupsByID($groupUid);
- if (count($groups) == 1) {
- $groupRealUid = reset($groups)->cn;
- }
- return $groupRealUid;
- }
- public function findGroupUid($groupUid) {
- return $this->findGroupUidLdap($groupUid);
- }
- /**
- * Add network group member.
- *
- * @param string $usrLogin - user login
- * @param object $group - @see getGroup
- * @return bool
- */
- private function _addUserGroupNetwork($usrLogin, $group) {
- if (!$group || empty($group->primaryKey) || empty($usrLogin)) return false;
- $groupUid = $group->primaryKey;
- $groupName = $group->realName;
- $groupRealUid = '';
- if ($group->type == 'network') {
- $groupRealUid = $group->primaryKey;// workgroup
- }
- else if (is_numeric($groupUid)) {
- $groupRealUid = $this->findGroupUid($groupUid);
- }
- if (!$groupRealUid) {
- if ($group->type == 'network') {
- throw new Exception("Brak dostępu do utworzenia grupy sieciowej '{$group->primaryKey}'");
- } else if ($group->type == 'local') {
- throw new Exception("Brak dostępu do utworzenia grupy lokalnej '{$group->primaryKey}'");
- }
- $this->createGroup($group);
- }
- $cmdDsclAuth = "dscl -u {$this->_rootUser} -P {$this->_rootPass} /LDAPv3/127.0.0.1 ";
- $cmd = "{$cmdDsclAuth} -append /Groups/{$groupRealUid} GroupMembership {$usrLogin} ";
- $cmdOut = null; $cmdRet = null;
- exec($cmd, $cmdOut, $cmdRet);
- if ($cmdRet != 0) {// TODO: may return 62 - user already in this group
- throw new Exception("Nie udało się dodać usera '{$usrLogin}' do grupy sieciowej '{$groupUid}'");
- }
- }
- /**
- * Remove network group member.
- *
- * @param string $usrLogin - user login
- * @param object $group - @see getGroup
- * @return bool
- */
- private function _removeUserGroupNetwork($usrLogin, $group) {
- if (!$group || empty($group->primaryKey) || empty($usrLogin)) return false;
- $groupUid = $group->primaryKey;
- $cmdDsclAuth = "dscl -u {$this->_rootUser} -P {$this->_rootPass} /LDAPv3/127.0.0.1 ";
- $cmd = "{$cmdDsclAuth} -delete /Groups/{$groupUid} GroupMembership {$usrLogin} ";
- $cmdOut = null; $cmdRet = null;
- exec($cmd, $cmdOut, $cmdRet);
- DBG::_('DBG_SU', '>1', "cmd({$cmd}) ret({$cmdRet})", $cmdOut, __CLASS__, __FUNCTION__, __LINE__);
- if ($cmdRet != 0) {
- throw new Exception("Nie udało się dodać usera '{$usrLogin}' z grupy sieciowej '{$groupUid}'");
- }
- }
- private function _removeUserUidFromGroupNetwork($usrAppleUid, $group) {
- if (!$group || empty($group->primaryKey) || empty($usrAppleUid)) return false;
- $groupUid = $group->primaryKey;
- $cmdDsclAuth = "dscl -u {$this->_rootUser} -P {$this->_rootPass} /LDAPv3/127.0.0.1 ";
- $cmd = "{$cmdDsclAuth} -delete /Groups/{$groupUid} GroupMembers {$usrAppleUid} ";
- $cmdOut = null; $cmdRet = null;
- exec($cmd, $cmdOut, $cmdRet);
- DBG::_('DBG_SU', '>1', "cmd({$cmd}) ret({$cmdRet})", $cmdOut, __CLASS__, __FUNCTION__, __LINE__);
- if ($cmdRet != 0) {
- throw new Exception("Nie udało się usunąć uid '{$usrAppleUid}' z grupy sieciowej '{$groupUid}'");
- }
- }
- /**
- * Add group member.
- *
- * @param string $usrLogin - user login
- * @param object $group - @see getGroup
- * @return bool
- */
- public function addUserGroup($usrLogin, $group) {
- // $groupUid, $groupName
- if ($group->type == 'local') {
- return $this->_addUserGroupLocal($usrLogin, $group);
- } else {
- return $this->_addUserGroupNetwork($usrLogin, $group);
- }
- }
- /**
- * Remove group member.
- *
- * @param string $usrLogin - user login
- * @param object $group - @see getGroup
- * @return bool
- */
- public function removeUserGroup($usrLogin, $group) {
- if ($group->type == 'local') {
- return $this->_removeUserGroupLocal($usrLogin, $group);
- } else {
- return $this->_removeUserGroupNetwork($usrLogin, $group);
- }
- }
- public function removeUserUidFromGroup($usrLogin, $group) {
- $rawUsrLdap = UsersLdapHelper::getUser($usrLogin, true);
- $rawUsrLdap = (!empty($rawUsrLdap))? $rawUsrLdap[0] : null;
- if (!$rawUsrLdap) throw new Exception("Cannot find user '{$usrLogin}'");
- $usrAppleUid = V::get('apple-generateduid', '', $rawUsrLdap);
- if (empty($usrAppleUid)) throw new Exception("Cannot find uid for user '{$usrLogin}'");
- DBG::_('DBG_SU', '>0', "CleanupAppleMemberUidTodoList user apple-generateduid({$usrAppleUid})", $group, __CLASS__, __FUNCTION__, __LINE__);
- if ($group->type == 'local') {
- //return $this->_removeUserGroupLocal($usrLogin, $group);
- } else {
- return $this->_removeUserUidFromGroupNetwork($usrAppleUid, $group);
- }
- }
- public function addNestedGroup($groupID, $nestedGroupID) {
- if ($groupID <= 0) return false;
- if ($nestedGroupID <= 0) return false;
- $group = $this->_getGroup($groupID);
- $groupNested = $this->_getGroup($nestedGroupID);
- if (!$group || !$groupNested) {
- return false;
- }
- $groupToAdd = $groupNested->primaryKey;
- $groupName = $group->primaryKey;
- // put a group called {$groupToAdd} into the {$groupName} group
- $cmd = "dseditgroup -o edit -n /LDAPv3/127.0.0.1 -u {$this->_rootUser} -P {$this->_rootPass} -a {$groupToAdd} -t group {$groupName}";
- $cmdOut = null; $cmdRet = null;
- exec($cmd, $cmdOut, $cmdRet);
- if ($cmdRet != 0) {
- DBG::_('DBG_SU', '>1', "cmd(" . str_replace($this->_rootPass, '***', $cmd) . ") ret({$cmdRet})", $cmdOut, __CLASS__, __FUNCTION__, __LINE__);
- $this->setError(1, "Nie udało się dodać grupy nadrzędnej '{$groupToAdd}' do grupy '{$groupName}' ", '(' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . ')');
- return false;
- }
- return true;
- }
- public function removeNestedGroup($groupID, $nestedGroupID) {
- if ($groupID <= 0) return false;
- if ($nestedGroupID <= 0) return false;
- $group = $this->_getGroup($groupID);
- $groupNested = $this->_getGroup($nestedGroupID);
- if (!$group || !$groupNested) {
- return false;
- }
- $groupToRemove = $groupNested->primaryKey;
- $groupName = $group->primaryKey;
- // put a group called {$groupToAdd} into the {$groupName} group
- $cmd = "dseditgroup -o edit -n /LDAPv3/127.0.0.1 -u {$this->_rootUser} -P {$this->_rootPass} -d {$groupToRemove} -t group {$groupName}";
- $cmdOut = null; $cmdRet = null;
- exec($cmd, $cmdOut, $cmdRet);
- if ($cmdRet != 0) {
- DBG::_('DBG_SU', '>1', "cmd(" . str_replace($this->_rootPass, '***', $cmd) . ") ret({$cmdRet})", $cmdOut, __CLASS__, __FUNCTION__, __LINE__);
- $this->setError(1, "Nie udało się usunąć grupy podrzędnej '{$groupToRemove}' z grupy '{$groupName}' ", '(' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . ')');
- return false;
- }
- return true;
- }
- public function changePassword($usrLogin, $passwd) {
- $cmdDsclAuth = "dscl -u {$this->_rootUser} -P {$this->_rootPass} /LDAPv3/127.0.0.1 ";
- $cmd = "{$cmdDsclAuth} -passwd /Users/{$usrLogin} \"{$passwd}\" ";
- $cmdOut = null; $cmdRet = null;
- exec($cmd, $cmdOut, $cmdRet);
- if ($cmdRet != 0) {
- return false;
- }
- return true;
- }
- }
|