diff --git a/lam/lib/account.inc b/lam/lib/account.inc index 3f7af507..c4839835 100644 --- a/lam/lib/account.inc +++ b/lam/lib/account.inc @@ -23,1113 +23,7 @@ $Id$ LDAP Account Manager functions used by account.php */ -/* This class contains all functions -* which are needed to manage the ldap cache -*/ -class cache { - function cache() { - $this->config =& $_SESSION['config']; - $this->ldap =& $_SESSION['ldap']; - $this->time = 0; - $this->attributes = array(); - } - var $ldapcache; // This variable contains the cache - var $attributes; // This variable contains a list and their scope of attributes which should be cached - var $config; // This is a reference to the config class in session - var $ldap; // This is a reference to the ldap class in session - var $time; // This is the laste timestamp ldap cache has been refreshed - - /* This function adds attributes to cache - * syntax of $attributes is array( scope1 => array ( attributes ), scope2 => array ( attributes ), ...) - */ - function add_cache($attributes) { - // Check input variable - $allowed_types = array ( 'user', 'group', 'host', 'domain', '*' ); - if (!is_array($attributes)) trigger_error(_('Argument of add_cache must be : array ( scope => array(attribute1(string), attribute2(string), ..), scope => ... ).'), E_USER_ERROR); - foreach ($attributes as $attribute) { - if (!is_array($attribute)) trigger_error(_('Argument of add_cache must be : array ( scope => array(attribute1(string), attribute2(string), ..), scope => ... ).'), E_USER_ERROR); - foreach ($attribute as $singleattribute) { - if (!is_string($singleattribute)) trigger_error(_('Argument of add_cache must be : array ( scope => array(attribute1(string), attribute2(string), ..), scope => ... ).'), E_USER_ERROR); - } - } - $scopes = array_keys($attributes); - foreach ($scopes as $scope) { - if (!@in_array($scope, $allowed_types)) trigger_error(sprintf(_('Invalid scope. Valid scopes are %s.'), implode(" ", $allowed_types)), E_USER_ERROR); - } - // Everything seems to be OK, start processing data - foreach ($scopes as $scope) { - for ($i=0; $iattributes[$scope])) $this->attributes[$scope][] = $attributes[$scope][$i]; - } - } - // Rebuild cache - $this->refresh_cache(true); - } - - /* This function returns an array ( dn1 => array(uidnumber1), dn2 => array(uidnumber2), ... ) - * - */ - function get_cache($attribute, $objectClass, $singlescope) { - $this->refresh_cache(); - // Check input variables - $allowed_types = array ( 'user', 'group', 'host', 'domain', '*' ); - if (!in_array($singlescope, $allowed_types)) trigger_error(sprintf(_('Invalid scope. Valid scopes are %s.'), implode(" ", $allowed_types)), E_USER_ERROR); - $line=-1; - for ($i=0; $iobjectClasses) || $i==-1; $i++) { - if (strpos($_SESSION['ldap']->objectClasses[$i], "NAME '$objectClass'")) $line = $i; - } - // Return error if objectClass isn't found - if ($line==-1) trigger_error (sprintf(_("objectClass %s required but not defined in ldap."), $objectClass), E_USER_WARNING); - - // Create list of all allowed attributes - for ($i=0; $ildap->objectClasses); $i++ ) { - if (strpos($this->ldap->objectClasses[$i], 'MUST (')) { - $string_withtail = substr($this->ldap->objectClasses[$i], strpos($this->ldap->objectClasses[$i], 'MUST (')+6); - // Now we have a string with all must-attributes - $string = substr($string_withtail, 0, strpos($string_withtail, ')')); - $string = trim($string); - $allowed_attributes = array_merge($allowed_attributes, explode(" $ ", $string)); - } - // create array with may-attributes - // Get startposition in string - if (strpos($this->ldap->objectClasses[$i], 'MAY (')) { - $string_withtail = substr($this->ldap->objectClasses[$i], strpos($this->ldap->objectClasses[$i], 'MAY (')+5); - // Now we have a string with all must-attributes - $string = substr($string_withtail, 0, strpos($string_withtail, ')')); - $string = trim($string); - $allowed_attributes = array_merge($allowed_attributes, explode(" $ ", $string)); - } - } - $allowed_attributes = array_unique($allowed_attributes); - if (!in_array($attribute, $allowed_attributes)) trigger_error(_('Attribute not defined in LDAP.'), E_USER_WARNING); - - // Everything seems to be OK, start processing data - $this->refresh_cache(); - if ($singlescope == '*') $scopes = $allowed_types; - else $scopes = array ( $singlescope ); - // Add cache entry dynamic - foreach ($scopes as $scope) { - if (!@in_array($attribute ,$this->attributes[$scope])) $add[$scope][] = $attribute; - } - if (count($add)!=0) $this->add_cache($add); - - foreach ($scopes as $scope) { - if (isset($this->ldapcache[$scope])) { - $DNs = array_keys($this->ldapcache[$scope]); - foreach ($DNs as $dn) { - if (isset($this->ldapcache[$scope][$dn][$attribute]) && in_array($objectClass, $this->ldapcache[$scope][$dn]['objectClass'])) { - // return string if only attribute exists only once - if (count($this->ldapcache[$scope][$dn][$attribute])==1) $return[$dn][] = $this->ldapcache[$scope][$dn][$attribute][0]; - else { - // else return array with all attributes - $return[$dn] = $this->ldapcache[$scope][$dn][$attribute]; - } - } - } - } - } - return $return; - } - - /* This functions returns the dn if a dn with $attribute=$value is found - * $values is the value $attribute is set to - * $scope is the scope where to search - */ - function in_cache($value, $attribute, $singlescope) { - $this->refresh_cache(); - // Check input variables - $allowed_types = array ( 'user', 'group', 'host', 'domain', '*' ); - if (!in_array($singlescope, $allowed_types)) trigger_error(sprintf(_('Invalid scope. Valid scopes are %s.'), implode(" ", $allowed_types)), E_USER_ERROR); - // Create list of all allowed attributes - for ($i=0; $ildap->objectClasses); $i++ ) { - if (strpos($this->ldap->objectClasses[$i], 'MUST (')) { - $string_withtail = substr($this->ldap->objectClasses[$i], strpos($this->ldap->objectClasses[$i], 'MUST (')+6); - // Now we have a string with all must-attributes - $string = substr($string_withtail, 0, strpos($string_withtail, ')')); - $string = trim($string); - $allowed_attributes = array_merge($allowed_attributes, explode(" $ ", $string)); - } - // create array with may-attributes - // Get startposition in string - if (strpos($this->ldap->objectClasses[$i], 'MAY (')) { - $string_withtail = substr($this->ldap->objectClasses[$i], strpos($this->ldap->objectClasses[$i], 'MAY (')+5); - // Now we have a string with all must-attributes - $string = substr($string_withtail, 0, strpos($string_withtail, ')')); - $string = trim($string); - $allowed_attributes = array_merge($allowed_attributes, explode(" $ ", $string)); - } - } - $allowed_attributes = array_unique($allowed_attributes); - if (!in_array($attribute, $allowed_attributes)) trigger_error(_('Attribute not defined in LDAP.'), E_USER_WARNING); - - // Everything seems to be OK, start processing data - $this->refresh_cache(); - if ($singlescope == '*') $scopes = $allowed_types; - else $scopes = array ( $singlescope ); - // Add cache entry dynamic - foreach ($scopes as $scope) { - if (!@in_array($attribute ,$this->attributes[$scope])) $add[$scope][] = $attribute; - } - if (count($add)!=0) $this->add_cache($add); - - foreach ($scopes as $scope) { - if (isset($this->ldapcache[$scope])) { - $DNs = array_keys($this->ldapcache[$scope]); - foreach ($DNs as $dn) { - if (is_array($this->ldapcache[$scope][$dn][$attribute])) { - if (in_array($value, $this->ldapcache[$scope][$dn][$attribute])) { - // Return value if value was found - return $dn; - } - } - } - } - } - // Return false if value wasn't found - return false; - } - - - /* This functions refreshs the cache - */ - function refresh_cache($rebuild=false) { - if ($time + $this->config->get_cacheTimeoutSec() < time() || $rebuild) { - // unset old cache - unset ($this->ldapcache); - $scopes = array_keys($this->attributes); - foreach ($scopes as $scope) { - // Get Scope - $function = '$suffix = $this->config->get_'.ucfirst($scope).'Suffix();'; - If ($scope != '*') eval($function); - else $suffix = ''; - // Get Data from ldap - $search = $this->attributes[$scope]; - $search[] = 'objectClass'; - $result = @ldap_search($this->ldap->server(), $suffix, 'objectClass=*', $search, 0); - // Write search result in array - $entry = @ldap_first_entry($this->ldap->server(), $result); - while ($entry) { - $dn = (ldap_get_dn($this->ldap->server(), $entry)); - $attr = ldap_get_attributes($this->ldap->server(), $entry); - // unset every count entry - unset ($attr['count']); - $attributes = array_keys($attr); - foreach ($attributes as $attribute) unset ($attr[$attribute]['count']); - // unset double entries - for ($i=0; $ildapcache[$scope][$dn] = $attr; - $entry = ldap_next_entry($this->ldap->server(), $entry); - } - } - $this->time = time(); - } - } - - /* This function update the cache when changes were - * made without refrehing the complete cache - */ - function update_cache($dn, $mode, $attributes=false) { - $allowed_modes = array ( 'add', 'remove', 'modify', 'delete_dn' ); - $allowed_types = array ( 'user', 'group', 'host', '*' ); - for ($i=0; $i"; - // *** fixme, where is get_DomainSuffix - If ($scope != '*') eval($function); - else $suffix = ''; - if (substr($suffix, $dn)) $singlescope = $allowed_types[$i]; - } - } - if (!in_array($singlescope, $allowed_types)) trigger_error(sprintf(_('Invalid scope. Valid scopes are %s.'), implode(" ", $allowed_types)), E_USER_ERROR); - if (!in_array($mode, $allowed_modes)) trigger_error(sprintf(_('Invalid mode. Valid modes are %s.'), implode(" ", $allowed_modes)), E_USER_ERROR); - // Everything seems to be OK, start processing data - // Get Scope - foreach ($allowed_types as $scope) { - $function = '$suffix = $this->config->get_'.ucfirst($scope).'Suffix();'; - eval($function); - if (strpos($dn, $suffix)) $singlescope = $scope; - } - if (!isset($singlescope)) trigger_error(sprintf(_('Invalid dn: %s. DN not covered by any suffix.'), $dn), E_USER_WARN); - // Refresh Cache - $this->refresh_cache(); - if (is_array($attributes)) - switch ($mode) { - case 'add': - $list = array_keys($attributes); - for ($i=0; $ildapcache[$singlescope][$dn][$list[$i]][] = $attributes[$list[$i]]; - break; - case 'remove': - $list = array_keys($attributes); - for ($i=0; $ildapcache[$singlescope][$dn][$list[$i]][$attributes[$list[$i]]])) - unset($this->ldapcache[$singlescope][$dn][$list[$i]][$attributes[$list[$i]]]); - break; - case 'modify': - $list = array_keys($attributes); - for ($i=0; $ildapcache[$singlescope][$dn][$list[$i]])) unset($this->ldapcache[$singlescope][$dn][$list[$i]]); - foreach ($attributes[$list[$i]] as $attribute) - $this->ldapcache[$singlescope][$dn][$list[$i]][] = $attributes[$list[$i]]; - } - } - else { - if ($mode=='delete_dn') - if (isset($this->ldapcache[$singlescope][$dn])) unset($this->ldapcache[$singlescope][$dn]); - } - } - - - /* This function will return the gidNumber to an existing groupname - * gidNumbers are taken from cache-array - */ - function getgid($groupname) { - $dn_groups = $_SESSION['cache']->get_cache('gidNumber', 'posixGroup', 'group'); - $DNs = array_keys($dn_groups); - foreach ($DNs as $DN) { - if (strpos($DN, $groupname)) - return $dn_groups[$DN][0]; - } - } - - - /* This function will return an array with all groupnames - * found in ldap. Groupnames are taken from cache-array. - */ - function findgroups() { - $dn_groups = $_SESSION['cache']->get_cache('cn', 'posixGroup', 'group'); - $DNs = array_keys($dn_groups); - foreach ($DNs as $DN) - $return[] = $dn_groups[$DN][0]; - return $return; - } - - - /* This function will return the groupname to an existing gidNumber - * groupnames are taken from cache-array - */ - function getgrnam($gidNumber) { - $dn_groups = $_SESSION['cache']->get_cache('gidNumber', 'posixGroup', 'group'); - $DNs = array_keys($dn_groups); - foreach ($DNs as $DN) { - if ($dn_groups[$DN][0]==$gidNumber) - $return = substr($DN, 3, strpos($DN, ',')-3); - } - return $return; - } - - } - - -class accountContainer { - // Constructor - function accountContainer($type, $base) { - /* Set the type of account. Valid - * types are: user, group, host - */ - // Check input variable - if (!is_string($type)) trigger_error(_('Argument of accountContainer must be string.'), E_USER_ERROR); - if (!is_string($base)) trigger_error(_('Argument of accountContainer must be string.'), E_USER_ERROR); - // *** fixme use global variable to determine allowed types - $allowed_types = array ( 'user', 'group', 'host', 'domain' ); - if (!in_array($type, $allowed_types)) trigger_error(_('Account type not recognized.'), E_USER_ERROR); - $this->type = $type; - $this->base = $base; - // Name of variables in session - $this->ldap = 'ldap'; - $this->config = 'config'; - $this->cache = 'cache'; - $this->header2 = 'header'; - $this->module['main'] = new main($this->base); - return 0; - } - - /* Array of all used attributes - * Syntax is attribute => array ( objectClass => MUST or MAY, ...) - */ - var $attributes; - /* This variale stores the type - * of account. Current unix, group, host are supported - */ - var $type; - var $ldap; // This is a reference to the ldap class in session - var $config; // This is a reference to the config class in session - // Localized part of HTML-Header - var $header2; - var $module; // This is an array with all module objects - // DN of the account - var $dn; - var $dn_orig; - // this are stores the module order - var $order; - // name of accountContainer so we can read other classes in accuontArray - var $base; - - /* Get the type of account. Valid - * types are: user, group, host - */ - function get_type() { - return $this->type; - } - - /* This function asks $this->module['main'] - * what to do next - */ - function continue_main($post) { - if ($this->module['main']->subpage=='') $this->module['main']->subpage='attributes'; - if ($post['form_main_reset']) { - $this->load_account($this->dn_orig); - } - else { - $function = '$result = $this->module[$this->order[$this->module[\'main\']->current_page]]->proccess_'.$this->module['main']->subpage.'($post);'; - eval ($function); - } - if (is_string($result)) $this->module['main']->subpage = $result; - if (is_int($result)) - for ($i=0; $iorder); $i++ ) - if ($post['form_main_'.$this->order[$i]]) { - $this->module['main']->current_page = $i; - $this->module['main']->subpage='attributes'; - } - // Write HTML-Code - echo $_SESSION[$this->header2]; - echo ""; - if ($this->dn_orig!='') echo _("Modify Account"); - else echo _("Create new Account"); - echo "\n"; - echo "\n"; - echo "\n"; - echo "
type."edit.php\" method=\"post\">\n"; - // Display errir-messages - if (is_array($result)) - foreach ($result as $result2) - if (is_array($result2)) - for ($i=0; $i\n"; - echo ""; - echo "\n"; - echo "
type."edit-dark\">type."edit-bright\">"; - echo _('Please select page:'); - echo "\n"; - // Loop for module - for ($i=0; $iorder); $i++ ) { - if ($this->order[$i]==$this->order[$this->module['main']->current_page] || !$this->module[$this->order[$i]]->module_ready() ) { - // print disabled button - echo "order[$i]."\" type=\"submit\" value=\""; - echo $this->module[$this->order[$i]]->get_alias(); - echo "\" disabled>\n
"; - } - else { - // print normal button - echo "order[$i]."\" type=\"submit\" value=\""; - echo $this->module[$this->order[$i]]->get_alias(); - echo "\">\n
"; - } - } - if ($this->dn_orig!='') echo "
\n"; - echo "
\n"; - echo "
type."edit-dark\">type."edit-bright\">"; - echo $this->module[$this->order[$this->module['main']->current_page]]->get_alias(); - echo "\n"; - // display html-code from mdule - $function = '$result = $this->module[$this->order[$this->module[\'main\']->current_page]]->display_html_'.$this->module['main']->subpage.'($post);'; - eval ($function); - $this->parse_html($this->order[$this->module['main']->current_page], $result); - // Display rest of html-page - echo "
\n"; - echo "\n"; - echo "\n"; - echo "\n"; - echo "\n"; - return 0; - } - - function parse_html($module, $input) { - if (is_array($input)) { - echo "\n"; - for ($i=0; $i\n"; - for ($j=0; $j\n"; - echo $input[$i][$j]['text'] . "\n"; - break; - case 'input': - echo "\n"; - $output = "\n"; - echo "
\n"; - if ($input[$i][$j]['legend']!='') echo "" . $input[$i][$j]['legend'] . "\n"; - $this->parse_html($module, $input[$i][$j]['value']); - echo "
\n"; - break; - case 'select': - if (!is_array($input[$i][$j]['options'])) $input[$i][$j]['options'] = array ( $input[$i][$j]['options'] ); - if (!is_array($input[$i][$j]['options_selected'])) $input[$i][$j]['options_selected'] = array ( $input[$i][$j]['options_selected'] ); - echo "\n"; - echo "\n"; - break; - case 'table': - echo "\n"; - $this->parse_html($module, $input[$i][$j]['value']); - echo "\n"; - break; - case 'help': - echo "\n"; - echo "" . _('Help') . "\n"; - break; - case 'message': - StatusMessage($input[$i][$j]['type'], $input[$i][$j]['headline'], $input[$i][$j]['text']); - break; - default: - echo "
\n"; - break; - } - } - echo "\n"; - } - } - echo "
Unrecognized type: " . $input[$i][$j]['kind'] . "
\n"; - } - - /* Add attributes to variable. Syntax is array( attribute = array ( objectClass1 => MUST|MAX, objectClass2 => MUST|MAY ), ... ) - */ - function add_attributes($objectClass) { - // loop through every existing objectlass and select current objectClass - $line=-1; - for ($i=0; $ildap]->objectClasses) || $i==-1; $i++) { - if (strpos($_SESSION[$this->ldap]->objectClasses[$i], "NAME '$objectClass'")) $line = $i; - } - // Return error if objectClass isn't found - if ($line==-1) trigger_error (sprintf(_("objectClass %s required but not defined in ldap."), $objectClass), E_USER_WARNING); - // create array with must-attributes - // Get startposition in string - if (strpos($_SESSION[$this->ldap]->objectClasses[$line], 'MUST (')) { - $string_withtail = substr($_SESSION[$this->ldap]->objectClasses[$line], strpos($_SESSION[$this->ldap]->objectClasses[$line], 'MUST (')+6); - // Now we have a string with all must-attributes - $string = substr($string_withtail, 0, strpos($string_withtail, ')')); - $string = trim($string); - $must = explode(" $ ", $string); - // Ad must - foreach ($must as $attribute) { - if (!isset($this->attributes[$attribute])) $this->attributes[$attribute][$objectClass] = 'MUST'; - else $this->attributes[$attribute][$objectClass] = 'MUST'; - } - } - // create array with may-attributes - // Get startposition in string - if (strpos($_SESSION[$this->ldap]->objectClasses[$line], 'MAY (')) { - $string_withtail = substr($_SESSION[$this->ldap]->objectClasses[$line], strpos($_SESSION[$this->ldap]->objectClasses[$line], 'MAY (')+5); - // Now we have a string with all must-attributes - $string = substr($string_withtail, 0, strpos($string_withtail, ')')); - $string = trim($string); - $may = explode(" $ ", $string); - // Ad may - foreach ($may as $attribute) { - if (!isset($this->attributes[$attribute])) $this->attributes[$attribute][$objectClass] = 'MAY'; - else $this->attributes[$attribute][$objectClass] = 'MAY'; - } - } - // Get attributes of subclasses - while (strpos($_SESSION[$this->ldap]->objectClasses[$line], "SUP ")) { - $string_withtail = substr($_SESSION[$this->ldap]->objectClasses[$line], strpos($_SESSION[$this->ldap]->objectClasses[$line], 'SUP ')+4); - $subclass = substr($string_withtail, 0, strpos($string_withtail, ' ')); - // Add account type to object - for ($i=0; $ildap]->objectClasses) || $i==-1; $i++) { - if (strpos($_SESSION[$this->ldap]->objectClasses[$i], "NAME '$subclass'")) $line = $i; - } - // Return error if objectClass isn't found - if ($line==-1) trigger_error (sprintf(_("objectClass %s required but not defined in ldap."), $objectClass), E_USER_WARNING); - // create array with must-attributes - // Get startposition in string - if (strpos($_SESSION[$this->ldap]->objectClasses[$line], 'MUST (')) { - $string_withtail = substr($_SESSION[$this->ldap]->objectClasses[$line], strpos($_SESSION[$this->ldap]->objectClasses[$line], 'MUST (')+6); - // Now we have a string with all must-attributes - $string = substr($string_withtail, 0, strpos($string_withtail, ')')); - $string = trim($string); - $must = explode(" $ ", $string); - // Ad must - foreach ($must as $attribute) { - if (!isset($this->attributes[$attribute])) $this->attributes[$attribute][$objectClass] = 'MUST'; - else $this->attributes[$attribute][$objectClass] = 'MUST'; - } - } - // create array with may-attributes - // Get startposition in string - if (strpos($_SESSION[$this->ldap]->objectClasses[$line], 'MAY (')) { - $string_withtail = substr($_SESSION[$this->ldap]->objectClasses[$line], strpos($_SESSION[$this->ldap]->objectClasses[$line], 'MAY (')+5); - // Now we have a string with all must-attributes - $string = substr($string_withtail, 0, strpos($string_withtail, ')')); - $string = trim($string); - $may = explode(" $ ", $string); - // Ad may - foreach ($may as $attribute) { - if (!isset($this->attributes[$attribute])) $this->attributes[$attribute][$objectClass] = 'MAY'; - else $this->attributes[$attribute][$objectClass] = 'MAY'; - } - } - } - } - - /* This function return ldap attributes - * Syntax is get_attributes($value, $scope) - * $scope = 'objectClass', $value = objectClass return value are all attributes of objectClass - * $scope = 'attribute', $value = attribute returns alle objectClasses which are using the attribute - */ - function get_attributes($value, $scope) { - if ($scope=='attribute' && isset($this->attributes[$value])) return $this->attributes[$value]; - if ($scope=='objectClass') { - $keys = array_keys($this->attributes); - foreach ($keys as $attribute) { - if (isset($this->attributes[$attribute][$value])) $return[$attribute] = $this->attributes[$attribute][$value]; - } - return $return; - } - return 0; - } - - /* This function return ldap attributes which are uses by $objectClass - * Syntax is get_attributes($objectClass) - * Return is an array with all allowed attributes - */ - function get_module_attributes($objectClass) { - // Add account type to object - $line=-1; - for ($i=0; $ildap]->objectClasses) || $i==-1; $i++) { - if (strpos($_SESSION[$this->ldap]->objectClasses[$i], "NAME '$objectClass'")) $line = $i; - } - // Return error if objectClass isn't found - if ($line==-1) trigger_error (sprintf(_("ObjectClass %s required but not defined in ldap."), $objectClass), E_USER_WARNING); - if (strpos($_SESSION[$this->ldap]->objectClasses[$line], 'MUST (')) { - $string_withtail = substr($_SESSION[$this->ldap]->objectClasses[$line], strpos($_SESSION[$this->ldap]->objectClasses[$line], 'MUST (')+6); - // Now we have a string with all must-attributes - $string = substr($string_withtail, 0, strpos($string_withtail, ')')); - $string = trim($string); - // Ad must - foreach (explode(" $ ", $string) as $attribute) { - $return[$attribute] = ''; - } - } - // create array with may-attributes - // Get startposition in string - if (strpos($_SESSION[$this->ldap]->objectClasses[$line], 'MAY (')) { - $string_withtail = substr($_SESSION[$this->ldap]->objectClasses[$line], strpos($_SESSION[$this->ldap]->objectClasses[$line], 'MAY (')+5); - // Now we have a string with all must-attributes - $string = substr($string_withtail, 0, strpos($string_withtail, ')')); - $string = trim($string); - // Ad may - foreach (explode(" $ ", $string) as $attribute) { - $return[$attribute] = ''; - } - } - // Get attributes of subclasses - while (strpos($_SESSION[$this->ldap]->objectClasses[$line], "SUP ")) { - $string_withtail = substr($_SESSION[$this->ldap]->objectClasses[$line], strpos($_SESSION[$this->ldap]->objectClasses[$line], 'SUP ')+4); - $subclass = substr($string_withtail, 0, strpos($string_withtail, ' ')); - // Add account type to object - for ($i=0; $ildap]->objectClasses) || $i==-1; $i++) { - if (strpos($_SESSION[$this->ldap]->objectClasses[$i], "NAME '$subclass'")) $line = $i; - } - // Return error if objectClass isn't found - if ($line==-1) trigger_error (sprintf(_("ObjectClass %s required but not defined in ldap."), $subclass), E_USER_WARNING); - // create array with must-attributes - // Get startposition in string - if (strpos($_SESSION[$this->ldap]->objectClasses[$line], 'MUST (')) { - $string_withtail = substr($_SESSION[$this->ldap]->objectClasses[$line], strpos($_SESSION[$this->ldap]->objectClasses[$line], 'MUST (')+6); - // Now we have a string with all must-attributes - $string = substr($string_withtail, 0, strpos($string_withtail, ')')); - $string = trim($string); - // Ad must - foreach (explode(" $ ", $string) as $attribute) { - $return[$attribute] = ''; - } - } - // create array with may-attributes - // Get startposition in string - if (strpos($_SESSION[$this->ldap]->objectClasses[$line], 'MAY (')) { - $string_withtail = substr($_SESSION[$this->ldap]->objectClasses[$line], strpos($_SESSION[$this->ldap]->objectClasses[$line], 'MAY (')+5); - // Now we have a string with all must-attributes - $string = substr($string_withtail, 0, strpos($string_withtail, ')')); - $string = trim($string); - // Ad may - foreach (explode(" $ ", $string) as $attribute) { - $return[$attribute] = ''; - } - } - } - $this->add_attributes($objectClass); - return $return; - } - - /* This function return ldap attributes which are uses by $objectClass - * Syntax is get_attributes($attributes, $orig) - * Return is an array as needed for $this->saveAccount() - */ - function save_module_attributes($attributes, $orig) { - // Get list of all "easy" attributes - $attr_names = array_keys($attributes); - // Get attributes which should be added - for ($i=0; $idn]['add'] = $toadd; - if (count($torem)!=0) $return[$this->dn]['remove'] = $torem; - if (count($tomodify)!=0) $return[$this->dn]['modify'] = $tomodify; - if (count($notchanged)!=0) $return[$this->dn]['notchanged'] = $notchanged; - return $return; - } - - - /* This function checks if all MUST-attribtues are set. - * If not it will return an array with all modules - * which have to be set first - */ - function check_attributes() { - $return = array(); - if (is_array($this->attributes)) { - // get named list of attributes - $attributes = array_keys($this->attributes); - for ($i=0; $iattributes[$attributes[$i]]); - for ($j=0; $jattributes[$attributes[$i]][$singleattribute[$j]]=='MUST') { - // Check if attribute is set - if ($this->module[$singleattribute[$j]]->attributes[$attributes[$i]]=='') - if (!in_array($singleattribute[$j], $return)) $return[] = $singleattribute[$j]; - } - } - } - return $return; - } - } - - /* This function adds an objectClass class (module) to accountContainer - */ - function add_objectClass($objectClass) { - $line=-1; - for ($i=0; $iobjectClasses) || $i==-1; $i++) { - if (strpos($_SESSION['ldap']->objectClasses[$i], "NAME '$objectClass'")) $line = $i; - } - // Return error if objectClass isn't found - if ($line==-1) trigger_error (_("objectClass $objectClass required but not defined in ldap."), E_USER_WARNING); - else { - // Add module if it exists - if (class_exists($objectClass)) { - $this->module[$objectClass] = new $objectClass($this->base); - } - else trigger_error (_("objectClass $objectClass required but no module found."), E_USER_WARNING); - } - return 0; - } - - /* This function will load an account. - * $dn is the dn of the account which should be loaded - */ - function load_account($dn) { - $search = substr($dn, 0, strpos($dn, ',')); - $result = ldap_search($_SESSION[$this->ldap]->server(), $dn, $search); - $entry = ldap_first_entry($_SESSION[$this->ldap]->server(), $result); - $this->dn = substr($dn, strpos($dn, ',')+1); - $this->dn_orig = $dn; - $attr = ldap_get_attributes($_SESSION[$this->ldap]->server(), $entry); - if (isset($attr['objectClass']['count'])) unset($attr['objectClass']['count']); - // load attributes - foreach ($attr['objectClass'] as $objectClass) { - $this->add_objectClass($objectClass); - if (isset($this->module[$objectClass])) $this->module[$objectClass]->load_attributes($attr); - } - $this->module['quota'] = new quota($this->base); - $this->module['quota']->load_attributes($attr); - - - // sortm modules and make all active because all required attributes should be set - $module = array_keys ($this->module); - $modulelist = array(); - // *** fixme add modules from config which should be used but not yet in loaded account - // *** fixme how to handle non ldap modules? - - // loop until all modules are in order. - // We don't want to loop forever - $remain = count($module) * count($module); - $order = array(); - while ( (count($module) != count($modulelist)) && ($remain!=0) ) { - $remain--; - foreach ($module as $moduleitem) { - $required = $this->module[$moduleitem]->get_dependencies($this->type); - $everything_found = true; - if (is_array($required['require'])) { - foreach ($required['require'] as $requireditem) - if (!in_array($reuquireditem, $modulelist)) $everthing_found = false; - } - if ($everything_found && !in_array($moduleitem, $order) ) $order[] = $moduleitem; - } - } - // Write Module-Order in variable - $this->order = $order; - return 0; - } - - function display_profile($post) { - $return = array(); - $post = array(); - $module = array_keys ($this->module); - foreach ($module as $singlemodule) { - // get list of display functions. - $list = $this->module[$singlemodule]->pages(); - foreach ($list as $item) { - $function = 'display_html_' . $item; - $page = $this->module[$singlemodule]->$function($post,true); - //eval($function); - $return = array_merge($return, $page); - } - } - return $return; - } - - function proccess_profile($post) { - $return = array(); - $module = array_keys ($this->module); - foreach ($module as $singlemodule) { - // get list of display functions. - $list = $this->module[$singlemodule]->pages(); - foreach ($list as $item) { - $function = 'display_html_' . $item; - $page = $this->module[$singlemodule]->$function($post,true); - //eval($function); - $return = array_merge($return, $page); - } - } - return $return; - } - - /* This function will prepare the object - * for a new account - */ - function new_account() { - $modulelist = array('posixAccount', 'sambaAccount'); - // *** fixme add modules from config which should be used but not yet in loaded account - foreach ($modulelist as $objectClass) $this->add_objectClass($objectClass); - - $module = array_keys ($this->module); - // loop until all modules are in order. - // We don't want to loop forever - $remain = count($module) * count($module); - $order = array(); - while ( (count($module) != count($modulelist)) && ($remain!=0) ) { - $remain--; - foreach ($module as $moduleitem) { - $required = $this->module[$moduleitem]->get_dependencies($this->type); - $everything_found = true; - if (is_array($required['require'])) { - foreach ($required['require'] as $requireditem) - if (!in_array($reuquireditem, $modulelist)) $everthing_found = false; - } - if ($everything_found && !in_array($moduleitem, $order) ) $order[] = $moduleitem; - } - } - // Write Module-Order in variable - $this->order = $order; - // *** fixme load*Profile must return array in the same way ldap_get_attributes does. - $function = '$newattributes = load'.ucfirst($this->type).'Profile(\'default\');'; - //eval($function); - return 0; - } - - /* This function will load an account. - */ - function save_account() { - $module = array_keys ($this->module); - $attributes = array(); - // load attributes - foreach ($module as $singlemodule) { - // load changes - $temp = $this->module[$singlemodule]->save_attributes(); - // merge changes - $DNs = array_keys($temp); - // *** fixme don't include references - $attributes = array_merge_recursive($temp, $attributes); - for ($i=0; $itype=='group') $search = 'cn'; - else $search = 'uid'; - $added = false; - print_r($attributes); - foreach ($attributes as $DN) { - if (isset($DN['modify'][$search][0]) && !$added) { - $attributes[$search.'='.$DN['modify'][$search][0].','.$this->dn] = $attributes[$this->dn]; - unset ($attributes[$this->dn]); - $this->dn = $search.'='.$DN['modify'][$search][0].','.$this->dn; - $added = true; - } - if (isset($DN['add'][$search][0]) && !$added) { - $attributes[$search.'='.$DN['add'][$search][0].','.$this->dn] = $attributes[$this->dn]; - unset ($attributes[$this->dn]); - $this->dn = $search.'='.$DN['add'][$search][0].','.$this->dn; - $added = true; - } - if (isset($DN['notchanged'][$search][0]) && !$added) { - $attributes[$search.'='.$DN['notchanged'][$search][0].','.$this->dn] = $attributes[$this->dn]; - unset ($attributes[$this->dn]); - $this->dn = $search.'='.$DN['notchanged'][$search][0].','.$this->dn; - $added = true; - } - } - // Add old dn if dn hasn't changed - if (!$added) { - $attributes[$this->dn_orig] = $attributes[$this->dn]; - unset ($attributes[$this->dn]); - $this->dn = $this->dn_orig; - } - // Set to true if an real error has happened - $stopprocessing = false; - // Add new DN - if (isset($attributes[$DNs[$i]]['errors'])) { - foreach ($attributes[$DNs[$i]]['errors'] as $singleerror) { - $errors[] = $singleerror; - if ($singleerror[0] = 'ERROR') $stopprocessing = true; - } - } - // fixme *** ad update_cache after every ldap-change - - if (!$stopprocessing) { - if ($this->dn != $this->dn_orig) { - // move existing DN - if ($this->dn_orig!='') { - // merge attributes together - $attr = array_merge_recursive($attributes[$this->dn]['add'], $attributes[$this->dn]['notchanged'], $attributes[$this->dn]['modify']); - $success = @ldap_add($_SESSION[$this->ldap]->server(), $this->dn, $attr); - if ($success) { - $_SESSION[$this->cache]->update_cache($this->$dn, 'add', $attr); - $success = @ldap_delete($_SESSION[$this->ldap]->server(), $this->dn_orig); - if (!$success) { - $errors[] = array('ERROR', 'LDAP', sprintf(_('Was unable to delete dn: %s.'), $this->dn_orig)); - $stopprocessing = true; - } - if ($success) - $_SESSION[$this->cache]->update_cache($this->$dn, 'delete_dn'); - } - if (!$success) { - $errors[] = array('ERROR', 'LDAP', sprintf(_('Was unable to create dn: %s. This is possible a bug. Please check your ldap logs and send a bug report if it is a possible bug.'), $this->dn)); - $stopprocessing = true; - } - } - // create complete new dn - else { - $attr = array_merge_recursive($attributes[$this->dn]['add'], $attributes[$this->dn]['notchanged'], $attributes[$this->dn]['modify']); - $success = @ldap_add($_SESSION[$this->ldap]->server(), $this->dn, $attributes[$this->dn]['add']); - if (!$success) { - $errors[] = array('ERROR', 'LDAP', sprintf(_('Was unable to create dn: %s. This is possible a bug. Please check your ldap logs and send a bug report if it is a possible bug.'), $this->dn)); - $stopprocessing = true; - } - else - $_SESSION[$this->cache]->update_cache($this->$dn, 'add', $attributes[$this->dn]['add']); - } - unset($attributes[$this->dn]); - } - } - $DNs = array_keys($attributes); - for ($i=0; $ildap]->server(), $DNs[$i], $attributes[$DNs[$i]]['modify']); - if (!$success) { - $errors[] = array('ERROR', 'LDAP', sprintf(_('Was unable to modify attribtues from dn: %s. This is possible a bug. Please check your ldap logs and send a bug report if it is a possible bug.'), $DNs[$i])); - $stopprocessing = true; - } - else - $_SESSION[$this->cache]->update_cache($this->$dn, 'modify', $attributes[$this->dn]['modify']); - } - // add attributes - if (isset($attributes[$DNs[$i]]['add']) && !$stopprocessing) { - $success = @ldap_mod_add($_SESSION[$this->ldap]->server(), $DNs[$i], $attributes[$DNs[$i]]['add']); - if (!$success) { - $errors[] = array('ERROR', 'LDAP', sprintf(_('Was unable to add attribtues to dn: %s. This is possible a bug. Please check your ldap logs and send a bug report if it is a possible bug.'), $DNs[$i])); - $stopprocessing = true; - } - else - $_SESSION[$this->cache]->update_cache($this->$dn, 'add', $attributes[$this->dn]['add']); - } - // removce attributes - if (isset($attributes[$DNs[$i]]['remove']) && !$stopprocessing) { - $success = @ldap_mod_del($_SESSION[$this->ldap]->server(), $DNs[$i], $attributes[$DNs[$i]]['remove']); - if (!$success) { - $errors[] = array('ERROR', 'LDAP', sprintf(_('Was unable to remove attribtues from dn: %s. This is possible a bug. Please check your ldap logs and send a bug report if it is a possible bug.'), $DNs[$i])); - $stopprocessing = true; - } - else - $_SESSION[$this->cache]->update_cache($this->$dn, 'remove', $attributes[$this->dn]['remove']); - } - } - } - - if (!$stopprocessing) { - foreach ($attributes as $DN) { - if (is_array($DN['lamdaemon']['command'])) $result = $this->lamdaemon($DN['lamdaemon']['command']); - // Error somewhere in lamdaemon - foreach ($result as $singleresult) { - if (is_array($singleresult)) { - if ($singleresult[0] = 'ERROR') $stopprocessing = true; - $temparray[0] = $singleresult[0]; - $temparray[1] = _($singleresult[1]); - $temparray[2] = _($singleresult[2]); - $errors[] = $temparray; - } - } - } - } - if (count($errors)!=0) return $errors; - return 0; - } - - function lamdaemon($commands) { - // get username and password of the current lam-admin - $ldap_q = $_SESSION[$this->ldap]->decrypt_login(); - /* $towrite has the following syntax: - * admin-username, admin-password, owner of homedir, 'home', operation='add' - * use escapeshellarg to make exec() shell-safe - */ - $towrite = escapeshellarg($_SESSION[$this->config]->scriptServer)." ".escapeshellarg($_SESSION[$this->config]->scriptPath)." ". - escapeshellarg($ldap_q[0]).' '.escapeshellarg($ldap_q[1]); - - $userstring = implode ("\n", $commands); - if (function_exists(proc_open)) { - // New Code, requires PHP 4.3 - $descriptorspec = array( - 0 => array("pipe", "r"), // stdin - 1 => array("pipe", "w"), // stout - 2 => array("file", "/dev/null", "a") // sterr - ); - $process = proc_open(escapeshellarg($_SESSION['lampath']."lib/lamdaemon.pl")." ".$towrite, - $descriptorspec, - $pipes); - if (is_resource($process)) { - /* perl-script is running - * $pipes[0] is writeable handle to child stdin - * $pipes[1] is readable handle to child stdout - * any error is send to /dev/null - */ - // Write to stdin - fwrite($pipes[0], $userstring); - } - fclose($pipes[0]); - while (!feof($pipes[1])) { - $output = fgets($pipes[1], 1024); - if ($output!='') $output_array[] = $output; - } - fclose($pipes[1]); - proc_close($process); - } - else { // PHP 4.3> - $command = escapeshellarg($_SESSION['lampath']."lib/lamdaemon.pl")." ".$towrite; - $pipe = popen("echo \"$userstring\"|$command" , 'r'); - while(!feof($pipe)) { - //$output .= fread($pipe, 1024); - $output = fgets($pipe, 1024); - if ($output!='') $output_array[] = $output; - } - pclose($pipe); - } - return $output_array; - } - - } /* Return a list of all shells listed in ../config/shells @@ -1243,7 +137,6 @@ function getdays() { return $days; } - /* This function creates all attributes stored in attrFlags. It's the same * syntax used in smbpasswd * $values is an array of samba flags as defined in account object @@ -1266,6 +159,4 @@ function smbflag($input) { return $flag; } - - ?> diff --git a/lam/lib/modules.inc b/lam/lib/modules.inc index d10cd9b2..99d6a33a 100644 --- a/lam/lib/modules.inc +++ b/lam/lib/modules.inc @@ -24,100 +24,850 @@ $Id$ */ -// returns an hash array (module => options) describing the options for an user profile -// the options follow the format specified in modules.spec (TODO filename) -function getUserProfileOptions() { - return array(); -} - -// returns an hash array (module => options) describing the options for an group profile -// the options follow the format specified in modules.spec (TODO filename) -function getGroupProfileOptions() { - return array(); -} - -// returns an hash array (module => options) describing the options for an host profile -// the options follow the format specified in modules.spec (TODO filename) -function getHostProfileOptions() { - return array(); -} - -// checks if the user profile values are correct -// $options is a hash array (attribute => value) with the entered values -// the values are all arrays with one or more elements -// returns an hash array containing the error messages, if any -// format of hash: attribute => array(message type, message header, message body, replacement array) -function checkUserProfileOptions($options) { -} - -// checks if the group profile values are correct -// $options is a hash array (attribute => value) with the entered values -// the values are all arrays with one or more elements -// returns an hash array containing the error messages, if any -// format of hash: attribute => array(message type, message header, message body, replacement array) -function checkGroupProfileOptions($options) { -} - -// checks if the host profile values are correct -// $options is a hash array (attribute => value) with the entered values -// the values are all arrays with one or more elements -// returns an hash array containing the error messages, if any -// format of hash: attribute => array(message type, message header, message body, replacement array) -function checkHostProfileOptions($options) { -} // returns the alias name of a module function getModuleAlias($name) { - return $name; -} + $eval = "$return = $name::get_alias()"; + eval ($eval); + return $return; + } // returns a hash array (module name => dependencies) of all user module dependencies // dependencies contains an array with two sub arrays: depends, conflicts // the elements of depends are either module names or an array of module names (OR-case) // the elements of conflicts are module names -function getUserModuleDependencies() { - return array("um1" => array("depends" => array("um4")), - "um2" => array("depends" => array("um4", array("um1", "um3"))), - "um3" => array("conflicts" => array("um1")), - "um4" => array()); -} +function getModuleDependencies($scope) { + // scope = suer, group, host, .... + // get module names. + $dir = opendir('../../lib/modules'); + while ($entry = readdir($dir)) + if (is_file('../../lib/modules/'.$entry)) { + $entry = substr($entry, 0, strpos('.')); + $eval = "$module = $entry::get_dependencies($scope)"; + eval ($eval); + $return[$entry] = $module; + } + return $return; + } -// returns a hash array (module name => dependencies) of all group module dependencies -// dependencies contains an array with two sub arrays: depends, conflicts -// the elements of depends are either module names or an array of module names (OR-case) -// the elements of conflicts are module names -function getGroupModuleDependencies() { - return array("gm1" => array("depends" => array("gm4")), - "gm2" => array("depends" => array("gm4"), "conflicts" => array("gm1")), - "gm3" => array("conflicts" => array("gm1")), - "gm4" => array()); -} - -// returns a hash array (module name => dependencies) of all host module dependencies -// dependencies contains an array with two sub arrays: depends, conflicts -// the elements of depends are either module names or an array of module names (OR-case) -// the elements of conflicts are module names -function getHostModuleDependencies() { - return array("hm1" => array("depends" => array("hm4")), - "hm2" => array("depends" => array("hm4"), "conflicts" => array("hm1")), - "hm3" => array("conflicts" => array("hm1")), - "hm4" => array()); -} // returns an array with all available user module names -function getAvailableUserModules() { - return array("um1", "um2", "um3", "um4"); -} +function getAvailableModules($scope) { + // scope = suer, group, host, .... + // get module names. + $dir = opendir('../../lib/modules'); + while ($entry = readdir($dir)) + if (is_file('../../lib/modules/'.$entry)) { + $entry = substr($entry, 0, strpos('.')); + $eval = "$module = $entry::get_dependencies($scope)"; + eval ($eval); + if ($module != -1) $return[] getModuleAlias($entry); + } + return $return; + } + + +class accountContainer { + // Constructor + function accountContainer($type, $base) { + /* Set the type of account. Valid + * types are: user, group, host + */ + // Check input variable + if (!is_string($type)) trigger_error(_('Argument of accountContainer must be string.'), E_USER_ERROR); + if (!is_string($base)) trigger_error(_('Argument of accountContainer must be string.'), E_USER_ERROR); + // *** fixme use global variable to determine allowed types + $allowed_types = array ( 'user', 'group', 'host', 'domain' ); + if (!in_array($type, $allowed_types)) trigger_error(_('Account type not recognized.'), E_USER_ERROR); + $this->type = $type; + $this->base = $base; + // Name of variables in session + $this->ldap = 'ldap'; + $this->config = 'config'; + $this->cache = 'cache'; + $this->header2 = 'header'; + $this->module['main'] = new main($this->base); + return 0; + } + + /* Array of all used attributes + * Syntax is attribute => array ( objectClass => MUST or MAY, ...) + */ + var $attributes; + /* This variale stores the type + * of account. Current unix, group, host are supported + */ + var $type; + var $ldap; // This is a reference to the ldap class in session + var $config; // This is a reference to the config class in session + // Localized part of HTML-Header + var $header2; + var $module; // This is an array with all module objects + // DN of the account + var $dn; + var $dn_orig; + // this are stores the module order + var $order; + // name of accountContainer so we can read other classes in accuontArray + var $base; + + /* Get the type of account. Valid + * types are: user, group, host + */ + function get_type() { + return $this->type; + } + + /* This function asks $this->module['main'] + * what to do next + */ + function continue_main($post) { + if ($this->module['main']->subpage=='') $this->module['main']->subpage='attributes'; + if ($post['form_main_reset']) { + $this->load_account($this->dn_orig); + } + else { + $function = '$result = $this->module[$this->order[$this->module[\'main\']->current_page]]->proccess_'.$this->module['main']->subpage.'($post);'; + eval ($function); + } + if (is_string($result)) $this->module['main']->subpage = $result; + if (is_int($result)) + for ($i=0; $iorder); $i++ ) + if ($post['form_main_'.$this->order[$i]]) { + $this->module['main']->current_page = $i; + $this->module['main']->subpage='attributes'; + } + // Write HTML-Code + echo $_SESSION[$this->header2]; + echo ""; + if ($this->dn_orig!='') echo _("Modify Account"); + else echo _("Create new Account"); + echo "\n"; + echo "\n"; + echo "\n"; + echo "
type."edit.php\" method=\"post\">\n"; + // Display errir-messages + if (is_array($result)) + foreach ($result as $result2) + if (is_array($result2)) + for ($i=0; $i\n"; + echo ""; + echo "\n"; + echo "
type."edit-dark\">type."edit-bright\">"; + echo _('Please select page:'); + echo "\n"; + // Loop for module + for ($i=0; $iorder); $i++ ) { + if ($this->order[$i]==$this->order[$this->module['main']->current_page] || !$this->module[$this->order[$i]]->module_ready() ) { + // print disabled button + echo "order[$i]."\" type=\"submit\" value=\""; + echo $this->module[$this->order[$i]]->get_alias(); + echo "\" disabled>\n
"; + } + else { + // print normal button + echo "order[$i]."\" type=\"submit\" value=\""; + echo $this->module[$this->order[$i]]->get_alias(); + echo "\">\n
"; + } + } + if ($this->dn_orig!='') echo "
\n"; + echo "
\n"; + echo "
type."edit-dark\">type."edit-bright\">"; + echo $this->module[$this->order[$this->module['main']->current_page]]->get_alias(); + echo "\n"; + // display html-code from mdule + $function = '$result = $this->module[$this->order[$this->module[\'main\']->current_page]]->display_html_'.$this->module['main']->subpage.'($post);'; + eval ($function); + $this->parse_html($this->order[$this->module['main']->current_page], $result); + // Display rest of html-page + echo "
\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + return 0; + } + + function parse_html($module, $input) { + if (is_array($input)) { + echo "\n"; + for ($i=0; $i\n"; + for ($j=0; $j\n"; + echo $input[$i][$j]['text'] . "\n"; + break; + case 'input': + echo "\n"; + $output = "\n"; + echo "
\n"; + if ($input[$i][$j]['legend']!='') echo "" . $input[$i][$j]['legend'] . "\n"; + $this->parse_html($module, $input[$i][$j]['value']); + echo "
\n"; + break; + case 'select': + if (!is_array($input[$i][$j]['options'])) $input[$i][$j]['options'] = array ( $input[$i][$j]['options'] ); + if (!is_array($input[$i][$j]['options_selected'])) $input[$i][$j]['options_selected'] = array ( $input[$i][$j]['options_selected'] ); + echo "\n"; + echo "\n"; + break; + case 'table': + echo "\n"; + $this->parse_html($module, $input[$i][$j]['value']); + echo "\n"; + break; + case 'help': + echo "\n"; + echo "" . _('Help') . "\n"; + break; + case 'message': + StatusMessage($input[$i][$j]['type'], $input[$i][$j]['headline'], $input[$i][$j]['text']); + break; + default: + echo "
\n"; + break; + } + } + echo "\n"; + } + } + echo "
Unrecognized type: " . $input[$i][$j]['kind'] . "
\n"; + } + + /* Add attributes to variable. Syntax is array( attribute = array ( objectClass1 => MUST|MAX, objectClass2 => MUST|MAY ), ... ) + */ + function add_attributes($objectClass) { + // loop through every existing objectlass and select current objectClass + $line=-1; + for ($i=0; $ildap]->objectClasses) || $i==-1; $i++) { + if (strpos($_SESSION[$this->ldap]->objectClasses[$i], "NAME '$objectClass'")) $line = $i; + } + // Return error if objectClass isn't found + if ($line==-1) trigger_error (sprintf(_("objectClass %s required but not defined in ldap."), $objectClass), E_USER_WARNING); + // create array with must-attributes + // Get startposition in string + if (strpos($_SESSION[$this->ldap]->objectClasses[$line], 'MUST (')) { + $string_withtail = substr($_SESSION[$this->ldap]->objectClasses[$line], strpos($_SESSION[$this->ldap]->objectClasses[$line], 'MUST (')+6); + // Now we have a string with all must-attributes + $string = substr($string_withtail, 0, strpos($string_withtail, ')')); + $string = trim($string); + $must = explode(" $ ", $string); + // Ad must + foreach ($must as $attribute) { + if (!isset($this->attributes[$attribute])) $this->attributes[$attribute][$objectClass] = 'MUST'; + else $this->attributes[$attribute][$objectClass] = 'MUST'; + } + } + // create array with may-attributes + // Get startposition in string + if (strpos($_SESSION[$this->ldap]->objectClasses[$line], 'MAY (')) { + $string_withtail = substr($_SESSION[$this->ldap]->objectClasses[$line], strpos($_SESSION[$this->ldap]->objectClasses[$line], 'MAY (')+5); + // Now we have a string with all must-attributes + $string = substr($string_withtail, 0, strpos($string_withtail, ')')); + $string = trim($string); + $may = explode(" $ ", $string); + // Ad may + foreach ($may as $attribute) { + if (!isset($this->attributes[$attribute])) $this->attributes[$attribute][$objectClass] = 'MAY'; + else $this->attributes[$attribute][$objectClass] = 'MAY'; + } + } + // Get attributes of subclasses + while (strpos($_SESSION[$this->ldap]->objectClasses[$line], "SUP ")) { + $string_withtail = substr($_SESSION[$this->ldap]->objectClasses[$line], strpos($_SESSION[$this->ldap]->objectClasses[$line], 'SUP ')+4); + $subclass = substr($string_withtail, 0, strpos($string_withtail, ' ')); + // Add account type to object + for ($i=0; $ildap]->objectClasses) || $i==-1; $i++) { + if (strpos($_SESSION[$this->ldap]->objectClasses[$i], "NAME '$subclass'")) $line = $i; + } + // Return error if objectClass isn't found + if ($line==-1) trigger_error (sprintf(_("objectClass %s required but not defined in ldap."), $objectClass), E_USER_WARNING); + // create array with must-attributes + // Get startposition in string + if (strpos($_SESSION[$this->ldap]->objectClasses[$line], 'MUST (')) { + $string_withtail = substr($_SESSION[$this->ldap]->objectClasses[$line], strpos($_SESSION[$this->ldap]->objectClasses[$line], 'MUST (')+6); + // Now we have a string with all must-attributes + $string = substr($string_withtail, 0, strpos($string_withtail, ')')); + $string = trim($string); + $must = explode(" $ ", $string); + // Ad must + foreach ($must as $attribute) { + if (!isset($this->attributes[$attribute])) $this->attributes[$attribute][$objectClass] = 'MUST'; + else $this->attributes[$attribute][$objectClass] = 'MUST'; + } + } + // create array with may-attributes + // Get startposition in string + if (strpos($_SESSION[$this->ldap]->objectClasses[$line], 'MAY (')) { + $string_withtail = substr($_SESSION[$this->ldap]->objectClasses[$line], strpos($_SESSION[$this->ldap]->objectClasses[$line], 'MAY (')+5); + // Now we have a string with all must-attributes + $string = substr($string_withtail, 0, strpos($string_withtail, ')')); + $string = trim($string); + $may = explode(" $ ", $string); + // Ad may + foreach ($may as $attribute) { + if (!isset($this->attributes[$attribute])) $this->attributes[$attribute][$objectClass] = 'MAY'; + else $this->attributes[$attribute][$objectClass] = 'MAY'; + } + } + } + } + + /* This function return ldap attributes + * Syntax is get_attributes($value, $scope) + * $scope = 'objectClass', $value = objectClass return value are all attributes of objectClass + * $scope = 'attribute', $value = attribute returns alle objectClasses which are using the attribute + */ + function get_attributes($value, $scope) { + if ($scope=='attribute' && isset($this->attributes[$value])) return $this->attributes[$value]; + if ($scope=='objectClass') { + $keys = array_keys($this->attributes); + foreach ($keys as $attribute) { + if (isset($this->attributes[$attribute][$value])) $return[$attribute] = $this->attributes[$attribute][$value]; + } + return $return; + } + return 0; + } + + /* This function return ldap attributes which are uses by $objectClass + * Syntax is get_attributes($objectClass) + * Return is an array with all allowed attributes + */ + function get_module_attributes($objectClass) { + // Add account type to object + $line=-1; + for ($i=0; $ildap]->objectClasses) || $i==-1; $i++) { + if (strpos($_SESSION[$this->ldap]->objectClasses[$i], "NAME '$objectClass'")) $line = $i; + } + // Return error if objectClass isn't found + if ($line==-1) trigger_error (sprintf(_("ObjectClass %s required but not defined in ldap."), $objectClass), E_USER_WARNING); + if (strpos($_SESSION[$this->ldap]->objectClasses[$line], 'MUST (')) { + $string_withtail = substr($_SESSION[$this->ldap]->objectClasses[$line], strpos($_SESSION[$this->ldap]->objectClasses[$line], 'MUST (')+6); + // Now we have a string with all must-attributes + $string = substr($string_withtail, 0, strpos($string_withtail, ')')); + $string = trim($string); + // Ad must + foreach (explode(" $ ", $string) as $attribute) { + $return[$attribute] = ''; + } + } + // create array with may-attributes + // Get startposition in string + if (strpos($_SESSION[$this->ldap]->objectClasses[$line], 'MAY (')) { + $string_withtail = substr($_SESSION[$this->ldap]->objectClasses[$line], strpos($_SESSION[$this->ldap]->objectClasses[$line], 'MAY (')+5); + // Now we have a string with all must-attributes + $string = substr($string_withtail, 0, strpos($string_withtail, ')')); + $string = trim($string); + // Ad may + foreach (explode(" $ ", $string) as $attribute) { + $return[$attribute] = ''; + } + } + // Get attributes of subclasses + while (strpos($_SESSION[$this->ldap]->objectClasses[$line], "SUP ")) { + $string_withtail = substr($_SESSION[$this->ldap]->objectClasses[$line], strpos($_SESSION[$this->ldap]->objectClasses[$line], 'SUP ')+4); + $subclass = substr($string_withtail, 0, strpos($string_withtail, ' ')); + // Add account type to object + for ($i=0; $ildap]->objectClasses) || $i==-1; $i++) { + if (strpos($_SESSION[$this->ldap]->objectClasses[$i], "NAME '$subclass'")) $line = $i; + } + // Return error if objectClass isn't found + if ($line==-1) trigger_error (sprintf(_("ObjectClass %s required but not defined in ldap."), $subclass), E_USER_WARNING); + // create array with must-attributes + // Get startposition in string + if (strpos($_SESSION[$this->ldap]->objectClasses[$line], 'MUST (')) { + $string_withtail = substr($_SESSION[$this->ldap]->objectClasses[$line], strpos($_SESSION[$this->ldap]->objectClasses[$line], 'MUST (')+6); + // Now we have a string with all must-attributes + $string = substr($string_withtail, 0, strpos($string_withtail, ')')); + $string = trim($string); + // Ad must + foreach (explode(" $ ", $string) as $attribute) { + $return[$attribute] = ''; + } + } + // create array with may-attributes + // Get startposition in string + if (strpos($_SESSION[$this->ldap]->objectClasses[$line], 'MAY (')) { + $string_withtail = substr($_SESSION[$this->ldap]->objectClasses[$line], strpos($_SESSION[$this->ldap]->objectClasses[$line], 'MAY (')+5); + // Now we have a string with all must-attributes + $string = substr($string_withtail, 0, strpos($string_withtail, ')')); + $string = trim($string); + // Ad may + foreach (explode(" $ ", $string) as $attribute) { + $return[$attribute] = ''; + } + } + } + $this->add_attributes($objectClass); + return $return; + } + + /* This function return ldap attributes which are uses by $objectClass + * Syntax is get_attributes($attributes, $orig) + * Return is an array as needed for $this->saveAccount() + */ + function save_module_attributes($attributes, $orig) { + // Get list of all "easy" attributes + $attr_names = array_keys($attributes); + // Get attributes which should be added + for ($i=0; $idn]['add'] = $toadd; + if (count($torem)!=0) $return[$this->dn]['remove'] = $torem; + if (count($tomodify)!=0) $return[$this->dn]['modify'] = $tomodify; + if (count($notchanged)!=0) $return[$this->dn]['notchanged'] = $notchanged; + return $return; + } + + + /* This function checks if all MUST-attribtues are set. + * If not it will return an array with all modules + * which have to be set first + */ + function check_attributes() { + $return = array(); + if (is_array($this->attributes)) { + // get named list of attributes + $attributes = array_keys($this->attributes); + for ($i=0; $iattributes[$attributes[$i]]); + for ($j=0; $jattributes[$attributes[$i]][$singleattribute[$j]]=='MUST') { + // Check if attribute is set + if ($this->module[$singleattribute[$j]]->attributes[$attributes[$i]]=='') + if (!in_array($singleattribute[$j], $return)) $return[] = $singleattribute[$j]; + } + } + } + return $return; + } + } + + /* This function adds an objectClass class (module) to accountContainer + */ + function add_objectClass($objectClass) { + $line=-1; + for ($i=0; $iobjectClasses) || $i==-1; $i++) { + if (strpos($_SESSION['ldap']->objectClasses[$i], "NAME '$objectClass'")) $line = $i; + } + // Return error if objectClass isn't found + if ($line==-1) trigger_error (_("objectClass $objectClass required but not defined in ldap."), E_USER_WARNING); + else { + // Add module if it exists + if (class_exists($objectClass)) { + $this->module[$objectClass] = new $objectClass($this->base); + } + else trigger_error (_("objectClass $objectClass required but no module found."), E_USER_WARNING); + } + return 0; + } + + /* This function will load an account. + * $dn is the dn of the account which should be loaded + */ + function load_account($dn) { + $search = substr($dn, 0, strpos($dn, ',')); + $result = ldap_search($_SESSION[$this->ldap]->server(), $dn, $search); + $entry = ldap_first_entry($_SESSION[$this->ldap]->server(), $result); + $this->dn = substr($dn, strpos($dn, ',')+1); + $this->dn_orig = $dn; + $attr = ldap_get_attributes($_SESSION[$this->ldap]->server(), $entry); + if (isset($attr['objectClass']['count'])) unset($attr['objectClass']['count']); + // load attributes + foreach ($attr['objectClass'] as $objectClass) { + $this->add_objectClass($objectClass); + if (isset($this->module[$objectClass])) $this->module[$objectClass]->load_attributes($attr); + } + $this->module['quota'] = new quota($this->base); + $this->module['quota']->load_attributes($attr); + + + // sortm modules and make all active because all required attributes should be set + $module = array_keys ($this->module); + $modulelist = array(); + // *** fixme add modules from config which should be used but not yet in loaded account + // *** fixme how to handle non ldap modules? + + // loop until all modules are in order. + // We don't want to loop forever + $remain = count($module) * count($module); + $order = array(); + while ( (count($module) != count($modulelist)) && ($remain!=0) ) { + $remain--; + foreach ($module as $moduleitem) { + $required = $this->module[$moduleitem]->get_dependencies($this->type); + $everything_found = true; + if (is_array($required['require'])) { + foreach ($required['require'] as $requireditem) + if (!in_array($reuquireditem, $modulelist)) $everthing_found = false; + } + if ($everything_found && !in_array($moduleitem, $order) ) $order[] = $moduleitem; + } + } + // Write Module-Order in variable + $this->order = $order; + return 0; + } + + function display_profile($post) { + $return = array(); + $post = array(); + $module = array_keys ($this->module); + foreach ($module as $singlemodule) { + // get list of display functions. + $list = $this->module[$singlemodule]->pages(); + foreach ($list as $item) { + $function = 'display_html_' . $item; + $page = $this->module[$singlemodule]->$function($post,true); + //eval($function); + $return = array_merge($return, $page); + } + } + return $return; + } + + function proccess_profile($post) { + $return = array(); + $module = array_keys ($this->module); + foreach ($module as $singlemodule) { + // get list of display functions. + $list = $this->module[$singlemodule]->pages(); + foreach ($list as $item) { + $function = 'display_html_' . $item; + $page = $this->module[$singlemodule]->$function($post,true); + //eval($function); + $return = array_merge($return, $page); + } + } + return $return; + } + + /* This function will prepare the object + * for a new account + */ + function new_account() { + $modulelist = array('posixAccount', 'sambaAccount'); + // *** fixme add modules from config which should be used but not yet in loaded account + foreach ($modulelist as $objectClass) $this->add_objectClass($objectClass); + + $module = array_keys ($this->module); + // loop until all modules are in order. + // We don't want to loop forever + $remain = count($module) * count($module); + $order = array(); + while ( (count($module) != count($modulelist)) && ($remain!=0) ) { + $remain--; + foreach ($module as $moduleitem) { + $required = $this->module[$moduleitem]->get_dependencies($this->type); + $everything_found = true; + if (is_array($required['require'])) { + foreach ($required['require'] as $requireditem) + if (!in_array($reuquireditem, $modulelist)) $everthing_found = false; + } + if ($everything_found && !in_array($moduleitem, $order) ) $order[] = $moduleitem; + } + } + // Write Module-Order in variable + $this->order = $order; + // *** fixme load*Profile must return array in the same way ldap_get_attributes does. + $function = '$newattributes = load'.ucfirst($this->type).'Profile(\'default\');'; + //eval($function); + return 0; + } + + /* This function will load an account. + */ + function save_account() { + $module = array_keys ($this->module); + $attributes = array(); + // load attributes + foreach ($module as $singlemodule) { + // load changes + $temp = $this->module[$singlemodule]->save_attributes(); + // merge changes + $DNs = array_keys($temp); + // *** fixme don't include references + $attributes = array_merge_recursive($temp, $attributes); + for ($i=0; $itype=='group') $search = 'cn'; + else $search = 'uid'; + $added = false; + print_r($attributes); + foreach ($attributes as $DN) { + if (isset($DN['modify'][$search][0]) && !$added) { + $attributes[$search.'='.$DN['modify'][$search][0].','.$this->dn] = $attributes[$this->dn]; + unset ($attributes[$this->dn]); + $this->dn = $search.'='.$DN['modify'][$search][0].','.$this->dn; + $added = true; + } + if (isset($DN['add'][$search][0]) && !$added) { + $attributes[$search.'='.$DN['add'][$search][0].','.$this->dn] = $attributes[$this->dn]; + unset ($attributes[$this->dn]); + $this->dn = $search.'='.$DN['add'][$search][0].','.$this->dn; + $added = true; + } + if (isset($DN['notchanged'][$search][0]) && !$added) { + $attributes[$search.'='.$DN['notchanged'][$search][0].','.$this->dn] = $attributes[$this->dn]; + unset ($attributes[$this->dn]); + $this->dn = $search.'='.$DN['notchanged'][$search][0].','.$this->dn; + $added = true; + } + } + // Add old dn if dn hasn't changed + if (!$added) { + $attributes[$this->dn_orig] = $attributes[$this->dn]; + unset ($attributes[$this->dn]); + $this->dn = $this->dn_orig; + } + // Set to true if an real error has happened + $stopprocessing = false; + // Add new DN + if (isset($attributes[$DNs[$i]]['errors'])) { + foreach ($attributes[$DNs[$i]]['errors'] as $singleerror) { + $errors[] = $singleerror; + if ($singleerror[0] = 'ERROR') $stopprocessing = true; + } + } + // fixme *** ad update_cache after every ldap-change + + if (!$stopprocessing) { + if ($this->dn != $this->dn_orig) { + // move existing DN + if ($this->dn_orig!='') { + // merge attributes together + $attr = array_merge_recursive($attributes[$this->dn]['add'], $attributes[$this->dn]['notchanged'], $attributes[$this->dn]['modify']); + $success = @ldap_add($_SESSION[$this->ldap]->server(), $this->dn, $attr); + if ($success) { + $_SESSION[$this->cache]->update_cache($this->$dn, 'add', $attr); + $success = @ldap_delete($_SESSION[$this->ldap]->server(), $this->dn_orig); + if (!$success) { + $errors[] = array('ERROR', 'LDAP', sprintf(_('Was unable to delete dn: %s.'), $this->dn_orig)); + $stopprocessing = true; + } + if ($success) + $_SESSION[$this->cache]->update_cache($this->$dn, 'delete_dn'); + } + if (!$success) { + $errors[] = array('ERROR', 'LDAP', sprintf(_('Was unable to create dn: %s. This is possible a bug. Please check your ldap logs and send a bug report if it is a possible bug.'), $this->dn)); + $stopprocessing = true; + } + } + // create complete new dn + else { + $attr = array_merge_recursive($attributes[$this->dn]['add'], $attributes[$this->dn]['notchanged'], $attributes[$this->dn]['modify']); + $success = @ldap_add($_SESSION[$this->ldap]->server(), $this->dn, $attributes[$this->dn]['add']); + if (!$success) { + $errors[] = array('ERROR', 'LDAP', sprintf(_('Was unable to create dn: %s. This is possible a bug. Please check your ldap logs and send a bug report if it is a possible bug.'), $this->dn)); + $stopprocessing = true; + } + else + $_SESSION[$this->cache]->update_cache($this->$dn, 'add', $attributes[$this->dn]['add']); + } + unset($attributes[$this->dn]); + } + } + $DNs = array_keys($attributes); + for ($i=0; $ildap]->server(), $DNs[$i], $attributes[$DNs[$i]]['modify']); + if (!$success) { + $errors[] = array('ERROR', 'LDAP', sprintf(_('Was unable to modify attribtues from dn: %s. This is possible a bug. Please check your ldap logs and send a bug report if it is a possible bug.'), $DNs[$i])); + $stopprocessing = true; + } + else + $_SESSION[$this->cache]->update_cache($this->$dn, 'modify', $attributes[$this->dn]['modify']); + } + // add attributes + if (isset($attributes[$DNs[$i]]['add']) && !$stopprocessing) { + $success = @ldap_mod_add($_SESSION[$this->ldap]->server(), $DNs[$i], $attributes[$DNs[$i]]['add']); + if (!$success) { + $errors[] = array('ERROR', 'LDAP', sprintf(_('Was unable to add attribtues to dn: %s. This is possible a bug. Please check your ldap logs and send a bug report if it is a possible bug.'), $DNs[$i])); + $stopprocessing = true; + } + else + $_SESSION[$this->cache]->update_cache($this->$dn, 'add', $attributes[$this->dn]['add']); + } + // removce attributes + if (isset($attributes[$DNs[$i]]['remove']) && !$stopprocessing) { + $success = @ldap_mod_del($_SESSION[$this->ldap]->server(), $DNs[$i], $attributes[$DNs[$i]]['remove']); + if (!$success) { + $errors[] = array('ERROR', 'LDAP', sprintf(_('Was unable to remove attribtues from dn: %s. This is possible a bug. Please check your ldap logs and send a bug report if it is a possible bug.'), $DNs[$i])); + $stopprocessing = true; + } + else + $_SESSION[$this->cache]->update_cache($this->$dn, 'remove', $attributes[$this->dn]['remove']); + } + } + } + + if (!$stopprocessing) { + foreach ($attributes as $DN) { + if (is_array($DN['lamdaemon']['command'])) $result = $this->lamdaemon($DN['lamdaemon']['command']); + // Error somewhere in lamdaemon + foreach ($result as $singleresult) { + if (is_array($singleresult)) { + if ($singleresult[0] = 'ERROR') $stopprocessing = true; + $temparray[0] = $singleresult[0]; + $temparray[1] = _($singleresult[1]); + $temparray[2] = _($singleresult[2]); + $errors[] = $temparray; + } + } + } + } + if (count($errors)!=0) return $errors; + return 0; + } + + function lamdaemon($commands) { + // get username and password of the current lam-admin + $ldap_q = $_SESSION[$this->ldap]->decrypt_login(); + /* $towrite has the following syntax: + * admin-username, admin-password, owner of homedir, 'home', operation='add' + * use escapeshellarg to make exec() shell-safe + */ + $towrite = escapeshellarg($_SESSION[$this->config]->scriptServer)." ".escapeshellarg($_SESSION[$this->config]->scriptPath)." ". + escapeshellarg($ldap_q[0]).' '.escapeshellarg($ldap_q[1]); + + $userstring = implode ("\n", $commands); + if (function_exists(proc_open)) { + // New Code, requires PHP 4.3 + $descriptorspec = array( + 0 => array("pipe", "r"), // stdin + 1 => array("pipe", "w"), // stout + 2 => array("file", "/dev/null", "a") // sterr + ); + $process = proc_open(escapeshellarg($_SESSION['lampath']."lib/lamdaemon.pl")." ".$towrite, + $descriptorspec, + $pipes); + if (is_resource($process)) { + /* perl-script is running + * $pipes[0] is writeable handle to child stdin + * $pipes[1] is readable handle to child stdout + * any error is send to /dev/null + */ + // Write to stdin + fwrite($pipes[0], $userstring); + } + fclose($pipes[0]); + while (!feof($pipes[1])) { + $output = fgets($pipes[1], 1024); + if ($output!='') $output_array[] = $output; + } + fclose($pipes[1]); + proc_close($process); + } + else { // PHP 4.3> + $command = escapeshellarg($_SESSION['lampath']."lib/lamdaemon.pl")." ".$towrite; + $pipe = popen("echo \"$userstring\"|$command" , 'r'); + while(!feof($pipe)) { + //$output .= fread($pipe, 1024); + $output = fgets($pipe, 1024); + if ($output!='') $output_array[] = $output; + } + pclose($pipe); + } + return $output_array; + } + + } -// returns an array with all available group module names -function getAvailableGroupModules() { - return array("gm1", "gm2", "gm3", "gm4"); -} -// returns an array with all available host module names -function getAvailableHostModules() { - return array("hm1", "hm2", "hm3", "hm4"); -} ?> diff --git a/lam/templates/account/groupedit.php b/lam/templates/account/groupedit.php index 98ad174a..6212d350 100644 --- a/lam/templates/account/groupedit.php +++ b/lam/templates/account/groupedit.php @@ -30,6 +30,8 @@ include_once('../../lib/profiles.inc'); // functions to load and save profiles include_once('../../lib/status.inc'); // Return error-message include_once('../../lib/pdf.inc'); // Return a pdf-file include_once('../../lib/ldap.inc'); // LDAP-functions +include_once('../../lib/modules.inc'); +include_once('../../lib/cache.inc'); /* We have to include all modules * before start session diff --git a/lam/templates/account/hostedit.php b/lam/templates/account/hostedit.php index 87328663..2cc8a872 100644 --- a/lam/templates/account/hostedit.php +++ b/lam/templates/account/hostedit.php @@ -30,6 +30,8 @@ include_once('../../lib/profiles.inc'); // functions to load and save profiles include_once('../../lib/status.inc'); // Return error-message include_once('../../lib/pdf.inc'); // Return a pdf-file include_once('../../lib/ldap.inc'); // LDAP-functions +include_once('../../lib/modules.inc'); +include_once('../../lib/cache.inc'); /* We have to include all modules * before start session diff --git a/lam/templates/account/useredit.php b/lam/templates/account/useredit.php index d5143c05..10c39e85 100644 --- a/lam/templates/account/useredit.php +++ b/lam/templates/account/useredit.php @@ -30,6 +30,8 @@ include_once('../../lib/profiles.inc'); // functions to load and save profiles include_once('../../lib/status.inc'); // Return error-message include_once('../../lib/pdf.inc'); // Return a pdf-file include_once('../../lib/ldap.inc'); // LDAP-functions +include_once('../../lib/modules.inc'); +include_once('../../lib/cache.inc'); /* We have to include all modules * before start session