summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com>2012-04-08 13:48:35 +0200
committerJeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com>2012-04-08 13:48:35 +0200
commit57f1e4019bac0cad4b82fed79f51b59af88e3136 (patch)
treee6bdcbfe5737212ca1b55f93760fecbeb9742f28
parentb05e0cec65cf7f461a655d601c0331c0f3d77513 (diff)
parenta84046a70f6f996474212dbf2f66f236026e3b72 (diff)
downloadwebadmin-57f1e4019bac0cad4b82fed79f51b59af88e3136.tar.gz
Merge branch 'master' of ssh://git.kolab.org/git/kolab-wap
-rw-r--r--lib/Auth/LDAP.php455
-rw-r--r--lib/api/kolab_api_service_form_value.php87
-rw-r--r--lib/api/kolab_api_service_group.php12
-rw-r--r--lib/api/kolab_api_service_user.php2
-rw-r--r--lib/client/kolab_client_task_group.php10
-rw-r--r--lib/kolab_client_task.php2
-rw-r--r--lib/locale/en_US.php1
-rw-r--r--public_html/js/kolab_admin.js2
8 files changed, 346 insertions, 225 deletions
diff --git a/lib/Auth/LDAP.php b/lib/Auth/LDAP.php
index cb8aaf8..cf64ff9 100644
--- a/lib/Auth/LDAP.php
+++ b/lib/Auth/LDAP.php
@@ -139,7 +139,7 @@ class LDAP
// 'uid=admin'.
$subject = $this->entry_dn($username);
- console($subject);
+ //console($subject);
if (!$subject) {
list($this->userid, $this->domain) = $this->_qualify_id($username);
@@ -253,6 +253,8 @@ class LDAP
public function allowed_attributes($objectclasses = Array())
{
+ //console("Listing allowed_attributes for objectclasses", $objectclasses);
+
$_schema = $this->init_schema();
if (!is_array($objectclasses)) {
@@ -303,7 +305,20 @@ class LDAP
public function effective_rights($subject)
{
- $attributes = array();
+ $effective_rights_control_oid = "1.3.6.1.4.1.42.2.27.9.5.2";
+
+ $supported_controls = $this->supported_controls();
+
+ if (!in_array($effective_rights_control_oid, $supported_controls)) {
+ error_log("No getEffectiveRights control in supportedControls");
+ return $this->legacy_rights($subject);
+ }
+
+ $attributes = array(
+ 'attributeLevelRights' => array(),
+ 'entryLevelRights' => array(),
+ );
+
$output = array();
$conf = Conf::get_instance();
@@ -347,9 +362,9 @@ class LDAP
//console("Executing command " . implode(' ', $command));
- exec(implode(' ', $command), $output);
+ exec(implode(' ', $command), $output, $return_code);
- //console("Output", $output);
+ //console("Output", $output, "Return code: " . $return_code);
$lines = array();
foreach ($output as $line_num => $line) {
@@ -760,42 +775,6 @@ class LDAP
return $domain_rootdn;
}
- private function init_schema()
- {
- $conf = Conf::get_instance();
-
- $this->_ldap_uri = $this->conf->get('ldap_uri');
- $this->_ldap_server = parse_url($this->_ldap_uri, PHP_URL_HOST);
- $this->_ldap_port = parse_url($this->_ldap_uri, PHP_URL_PORT);
- $this->_ldap_scheme = parse_url($this->_ldap_uri, PHP_URL_SCHEME);
-
- require_once("Net/LDAP2.php");
-
- $_ldap_cfg = Array(
- 'host' => $this->_ldap_server,
- 'port' => $this->_ldap_port,
- 'tls' => false,
- 'version' => 3,
- 'binddn' => $conf->get('bind_dn'),
- 'bindpw' => $conf->get('bind_pw')
- );
-
- $_ldap_schema_cache_cfg = Array(
- 'path' => "/tmp/Net_LDAP2_Schema.cache",
- 'max_age' => 86400,
- );
-
- $_ldap_schema_cache = new Net_LDAP2_SimpleFileSchemaCache($_ldap_schema_cache_cfg);
-
- $_ldap = Net_LDAP2::connect($_ldap_cfg);
-
- $result = $_ldap->registerSchemaCache($_ldap_schema_cache);
-
- $_schema = $_ldap->schema('cn=schema');
-
- return $_schema;
- }
-
public function search($base_dn, $search_filter = '(objectClass=*)', $attributes = array('*'))
{
//console("Auth::LDAP::search", $base_dn);
@@ -840,47 +819,54 @@ class LDAP
return $this->_search($base_dn, $filter);
}
- private function users_list($attributes = array(), $search = array())
+ private function entry_dn($subject)
{
- $conf = Conf::get_instance();
+ //console("entry_dn on subject $subject");
+ $is_dn = ldap_explode_dn($subject, 1);
+ //console($is_dn);
- $base_dn = $conf->get('user_base_dn');
+ if (is_array($is_dn) && array_key_exists("count", $is_dn) && $is_dn["count"] > 0) {
+ return $subject;
+ }
- if (!$base_dn)
- $base_dn = $conf->get('base_dn');
+ $unique_attr = $this->unique_attribute();
+ $subject = $this->entry_find_by_attribute(array($unique_attr => $subject));
- $filter = $conf->get('user_filter');
+ if (!empty($subject)) {
+ return key($subject);
+ }
+ }
- if (empty($attributes) || !is_array($attributes)) {
- $attributes = array('*');
+ private function entry_find_by_attribute($attribute)
+ {
+ if (empty($attribute) || !is_array($attribute) || count($attribute) > 1) {
+ return false;
}
- if ($s_filter = $this->_search_filter($search)) {
- // join search filter with objectClass filter
- $filter = '(&' . $filter . $s_filter . ')';
+ if (empty($attribute[key($attribute)])) {
+ return false;
}
- return $this->_search($base_dn, $filter, $attributes);
- }
+ $filter = "(&";
- private function roles_list($attributes = array(), $search = array())
- {
- $conf = Conf::get_instance();
+ foreach ($attribute as $key => $value) {
+ $filter .= "(" . $key . "=" . $value . ")";
+ }
- $base_dn = $conf->get('base_dn');
- // TODO: From config
- $filter = "(&(objectclass=ldapsubentry)(objectclass=nsroledefinition))";
+ $filter .= ")";
- if (empty($attributes) || !is_array($attributes)) {
- $attributes = array('*');
- }
+ $base_dn = $this->domain_root_dn($this->domain);
- if ($s_filter = $this->_search_filter($search)) {
- // join search filter with objectClass filter
- $filter = '(&' . $filter . $s_filter . ')';
- }
+ $result = self::normalize_result($this->_search($base_dn, $filter, array_keys($attribute)));
- return $this->_search($base_dn, $filter, $attributes);
+ if (count($result) > 0) {
+ error_log("Results found: " . implode(', ', array_keys($result)));
+ return $result;
+ }
+ else {
+ error_log("No result");
+ return false;
+ }
}
private function groups_list($attributes = array(), $search = array())
@@ -906,145 +892,100 @@ class LDAP
return $this->_search($base_dn, $filter, $attributes);
}
- public static function normalize_result($__result)
+ private function init_schema()
{
- if (!is_array($__result)) {
- return array();
- }
-
$conf = Conf::get_instance();
- $dn_attr = $conf->get($conf->get('kolab', 'auth_mechanism'), 'domain_name_attribute');
- $result = array();
-
- for ($x = 0; $x < $__result["count"]; $x++) {
- $dn = $__result[$x]['dn'];
- $result[$dn] = array();
- for ($y = 0; $y < $__result[$x]["count"]; $y++) {
- $attr = $__result[$x][$y];
- if ($__result[$x][$attr]["count"] == 1) {
- switch ($attr) {
- case "objectclass":
- $result[$dn][$attr] = strtolower($__result[$x][$attr][0]);
- break;
- default:
- $result[$dn][$attr] = $__result[$x][$attr][0];
- break;
- }
- }
- else {
- $result[$dn][$attr] = array();
- for ($z = 0; $z < $__result[$x][$attr]["count"]; $z++) {
- // The first result in the array is the primary domain.
- if ($z == 0 && $attr == $dn_attr) {
- $result[$dn]['primary_domain'] = $__result[$x][$attr][$z];
- }
-
- switch ($attr) {
- case "objectclass":
- $result[$dn][$attr][] = strtolower($__result[$x][$attr][$z]);
- break;
- default:
- $result[$dn][$attr][] = $__result[$x][$attr][$z];
- break;
- }
- }
- }
- }
- }
-
- return $result;
- }
-
- private function entry_find_by_attribute($attribute)
- {
- if (empty($attribute) || !is_array($attribute) || count($attribute) > 1) {
- return false;
- }
-
- if (empty($attribute[key($attribute)])) {
- return false;
- }
-
- $filter = "(&";
+ $this->_ldap_uri = $this->conf->get('ldap_uri');
+ $this->_ldap_server = parse_url($this->_ldap_uri, PHP_URL_HOST);
+ $this->_ldap_port = parse_url($this->_ldap_uri, PHP_URL_PORT);
+ $this->_ldap_scheme = parse_url($this->_ldap_uri, PHP_URL_SCHEME);
- foreach ($attribute as $key => $value) {
- $filter .= "(" . $key . "=" . $value . ")";
- }
+ require_once("Net/LDAP2.php");
- $filter .= ")";
+ $_ldap_cfg = Array(
+ 'host' => $this->_ldap_server,
+ 'port' => $this->_ldap_port,
+ 'tls' => false,
+ 'version' => 3,
+ 'binddn' => $conf->get('bind_dn'),
+ 'bindpw' => $conf->get('bind_pw')
+ );
- $base_dn = $this->domain_root_dn($this->domain);
+ $_ldap_schema_cache_cfg = Array(
+ 'path' => "/tmp/" . $this->_ldap_server . ":" . ($this->_ldap_port ? $this->_ldap_port : '389') . "-Net_LDAP2_Schema.cache",
+ 'max_age' => 86400,
+ );
- $result = self::normalize_result($this->_search($base_dn, $filter, array_keys($attribute)));
+ $_ldap_schema_cache = new Net_LDAP2_SimpleFileSchemaCache($_ldap_schema_cache_cfg);
- if (count($result) > 0) {
- error_log("Results found: " . implode(', ', array_keys($result)));
- return $result;
- }
- else {
- error_log("No result");
- return false;
- }
- }
+ $_ldap = Net_LDAP2::connect($_ldap_cfg);
- private function entry_dn($subject)
- {
- console("entry_dn on subject $subject");
- $is_dn = ldap_explode_dn($subject, 1);
- console($is_dn);
+ $result = $_ldap->registerSchemaCache($_ldap_schema_cache);
- if (is_array($is_dn) && array_key_exists("count", $is_dn) && $is_dn["count"] > 0) {
- return $subject;
+ // TODO: We should learn what LDAP tech. we're running against.
+ // Perhaps with a scope base objectclass recognize rootdse entry
+ $schema_root_dn = $conf->get('schema_root_dn');
+ if (!$schema_root_dn) {
+ $_schema = $_ldap->schema();
}
- $unique_attr = $this->unique_attribute();
- $subject = $this->entry_find_by_attribute(array($unique_attr => $subject));
-
- if (!empty($subject)) {
- return key($subject);
- }
+ return $_schema;
}
- private function parse_attribute_level_rights($attribute_value)
+ private function legacy_rights($subject)
{
- $attribute_value = str_replace(", ", ",", $attribute_value);
- $attribute_values = explode(",", $attribute_value);
-
- $attribute_value = array();
+ $subject_dn = $this->entry_dn($subject);
- foreach ($attribute_values as $access_right) {
- $access_right_components = explode(":", $access_right);
- $access_attribute = strtolower(array_shift($access_right_components));
- $access_value = array_shift($access_right_components);
+ $user_is_admin = false;
+ $user_is_self = false;
- $attribute_value[$access_attribute] = array();
+ // List group memberships
+ $user_groups = $this->find_user_groups($_SESSION['user']->user_bind_dn);
+ //console("User's groups", $user_groups);
- for ($i = 0; $i < strlen($access_value); $i++) {
- $method = $this->attribute_level_rights_map[substr($access_value, $i, 1)];
+ foreach ($user_groups as $user_group_dn) {
+ if ($user_is_admin)
+ continue;
- if (!in_array($method, $attribute_value[$access_attribute])) {
- $attribute_value[$access_attribute][] = $method;
+ $user_group_dn_components = ldap_explode_dn($user_group_dn, 1);
+ unset($user_group_dn_components["count"]);
+ $user_group_cn = array_shift($user_group_dn_components);
+ if (in_array($user_group_cn, array('admin', 'maintainer', 'domain-maintainer'))) {
+ // All rights default to write.
+ $user_is_admin = true;
+ } else {
+ // The user is a regular user, see if the subject is the same has the
+ // user session's bind_dn.
+ if ($subject_dn == $_SESSION['user']->user_bind_dn) {
+ $user_is_self = true;
}
}
}
- return $attribute_value;
- }
+ if ($user_is_admin) {
+ $standard_rights = array("add", "delete", "read", "write");
+ } elseif ($user_is_self) {
+ $standard_rights = array("read", "write");
+ } else {
+ $standard_rights = array("read");
+ }
- private function parse_entry_level_rights($attribute_value)
- {
- $_attribute_value = array();
+ $rights = array(
+ 'entryLevelRights' => $standard_rights,
+ 'attributeLevelRights' => array(),
+ );
- for ($i = 0; $i < strlen($attribute_value); $i++) {
- $method = $this->entry_level_rights_map[substr($attribute_value, $i, 1)];
+ $subject = self::normalize_result($this->_search($subject_dn));
- if (!in_array($method, $_attribute_value)) {
- $_attribute_value[] = $method;
- }
+ $attributes = $this->allowed_attributes($subject[$subject_dn]['objectclass']);
+ $attributes = array_merge($attributes['may'], $attributes['must']);
+
+ foreach ($attributes as $attribute) {
+ $rights['attributeLevelRights'][$attribute] = $standard_rights;
}
- return $_attribute_value;
+ return $rights;
}
private function modify_entry($subject_dn, $old_attrs, $new_attrs)
@@ -1233,6 +1174,153 @@ class LDAP
}
}
+ private function parse_attribute_level_rights($attribute_value)
+ {
+ $attribute_value = str_replace(", ", ",", $attribute_value);
+ $attribute_values = explode(",", $attribute_value);
+
+ $attribute_value = array();
+
+ foreach ($attribute_values as $access_right) {
+ $access_right_components = explode(":", $access_right);
+ $access_attribute = strtolower(array_shift($access_right_components));
+ $access_value = array_shift($access_right_components);
+
+ $attribute_value[$access_attribute] = array();
+
+ for ($i = 0; $i < strlen($access_value); $i++) {
+ $method = $this->attribute_level_rights_map[substr($access_value, $i, 1)];
+
+ if (!in_array($method, $attribute_value[$access_attribute])) {
+ $attribute_value[$access_attribute][] = $method;
+ }
+ }
+ }
+
+ return $attribute_value;
+ }
+
+ private function parse_entry_level_rights($attribute_value)
+ {
+ $_attribute_value = array();
+
+ for ($i = 0; $i < strlen($attribute_value); $i++) {
+ $method = $this->entry_level_rights_map[substr($attribute_value, $i, 1)];
+
+ if (!in_array($method, $_attribute_value)) {
+ $_attribute_value[] = $method;
+ }
+ }
+
+ return $_attribute_value;
+ }
+
+ private function roles_list($attributes = array(), $search = array())
+ {
+ $conf = Conf::get_instance();
+
+ $base_dn = $conf->get('base_dn');
+ // TODO: From config
+ $filter = "(&(objectclass=ldapsubentry)(objectclass=nsroledefinition))";
+
+ if (empty($attributes) || !is_array($attributes)) {
+ $attributes = array('*');
+ }
+
+ if ($s_filter = $this->_search_filter($search)) {
+ // join search filter with objectClass filter
+ $filter = '(&' . $filter . $s_filter . ')';
+ }
+
+ return $this->_search($base_dn, $filter, $attributes);
+ }
+
+ private function supported_controls()
+ {
+ $conf = Conf::get_instance();
+
+ $this->_bind($conf->get('bind_dn'), $conf->get('bind_pw'));
+
+ $result = ldap_read($this->conn, "", "(objectclass=*)", array("supportedControl"));
+ $result = ldap_get_entries($this->conn, $result);
+ $result = self::normalize_result($result);
+
+ return $result['']['supportedcontrol'];
+ }
+
+ private function users_list($attributes = array(), $search = array())
+ {
+ $conf = Conf::get_instance();
+
+ $base_dn = $conf->get('user_base_dn');
+
+ if (!$base_dn)
+ $base_dn = $conf->get('base_dn');
+
+ $filter = $conf->get('user_filter');
+
+ if (empty($attributes) || !is_array($attributes)) {
+ $attributes = array('*');
+ }
+
+ if ($s_filter = $this->_search_filter($search)) {
+ // join search filter with objectClass filter
+ $filter = '(&' . $filter . $s_filter . ')';
+ }
+
+ return $this->_search($base_dn, $filter, $attributes);
+ }
+
+ public static function normalize_result($__result)
+ {
+ if (!is_array($__result)) {
+ return array();
+ }
+
+ $conf = Conf::get_instance();
+
+ $dn_attr = $conf->get($conf->get('kolab', 'auth_mechanism'), 'domain_name_attribute');
+ $result = array();
+
+ for ($x = 0; $x < $__result["count"]; $x++) {
+ $dn = $__result[$x]['dn'];
+ $result[$dn] = array();
+ for ($y = 0; $y < $__result[$x]["count"]; $y++) {
+ $attr = $__result[$x][$y];
+ if ($__result[$x][$attr]["count"] == 1) {
+ switch ($attr) {
+ case "objectclass":
+ $result[$dn][$attr] = array(strtolower($__result[$x][$attr][0]));
+ break;
+ default:
+ $result[$dn][$attr] = $__result[$x][$attr][0];
+ break;
+ }
+ }
+ else {
+ $result[$dn][$attr] = array();
+ for ($z = 0; $z < $__result[$x][$attr]["count"]; $z++) {
+ // The first result in the array is the primary domain.
+ if ($z == 0 && $attr == $dn_attr) {
+ $result[$dn]['primary_domain'] = $__result[$x][$attr][$z];
+ }
+
+ switch ($attr) {
+ case "objectclass":
+ $result[$dn][$attr][] = strtolower($__result[$x][$attr][$z]);
+ break;
+ default:
+ $result[$dn][$attr][] = $__result[$x][$attr][$z];
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return $result;
+ }
+
/**
* Result sorting callback for uasort()
*/
@@ -1731,16 +1819,18 @@ class LDAP
$entry = self::normalize_result($this->_search($dn));
- //console("ENTRIES for \$dn $dn", $entries);
+ //console("ENTRIES for \$dn $dn", $entry);
foreach ($entry[$dn] as $attribute => $value) {
if ($attribute == "objectclass") {
foreach ($value as $objectclass) {
switch (strtolower($objectclass)) {
case "groupofnames":
+ case "kolabgroupofnames":
$group_members = array_merge($group_members, $this->_list_group_member($dn, $entry[$dn]['member'], $recurse));
break;
case "groupofuniquenames":
+ case "kolabgroupofuniquenames":
$group_members = array_merge($group_members, $this->_list_group_uniquemember($dn, $entry[$dn]['uniquemember'], $recurse));
break;
case "groupofurls":
@@ -1759,6 +1849,9 @@ class LDAP
error_log("Called _list_group_member(" . $dn . ")");
$group_members = array();
+
+ $members = (array)($members);
+
if (empty($members)) {
return $group_members;
}
@@ -1799,6 +1892,8 @@ class LDAP
return $group_members;
}
+ $uniquemembers = (array)($uniquemembers);
+
if (is_string($uniquemembers)) {
//console("uniquemember for entry is not an array");
$uniquemembers = (array)($uniquemembers);
@@ -1835,7 +1930,7 @@ class LDAP
$group_members = array();
- foreach ((array)$memberurls as $url) {
+ foreach ((array)($memberurls) as $url) {
$ldap_uri_components = $this->_parse_memberurl($url);
$entries = self::normalize_result($this->_search($ldap_uri_components[3], $ldap_uri_components[6]));
diff --git a/lib/api/kolab_api_service_form_value.php b/lib/api/kolab_api_service_form_value.php
index b5371da..300da36 100644
--- a/lib/api/kolab_api_service_form_value.php
+++ b/lib/api/kolab_api_service_form_value.php
@@ -562,8 +562,11 @@ class kolab_api_service_form_value extends kolab_api_service
}
return $list;
+ }
-
+ private function list_options_member($postdata, $attribs = array())
+ {
+ return $this->_list_options_members($postdata, $attribs);
}
private function list_options_nsrole($postdata, $attribs = array())
@@ -598,45 +601,9 @@ class kolab_api_service_form_value extends kolab_api_service
return $list;
}
-
private function list_options_uniquemember($postdata, $attribs = array())
{
- $service = $this->controller->get_service('users');
-
- $keyword = array('value' => $postdata['search']);
- $data = array(
- 'attributes' => array('displayname', 'mail'),
- 'page_size' => 15,
- 'search' => array(
- 'displayname' => $keyword,
- 'cn' => $keyword,
- 'mail' => $keyword,
- ),
- );
-
- $result = $service->users_list(null, $data);
- $list = $result['list'];
-
- $service = $this->controller->get_service('groups');
- $data['attributes'] = array('cn', 'mail');
-
- $result = $service->groups_list(null, $data);
- $list = array_merge($list, $result['list']);
-
- // convert to key=>value array
- foreach ($list as $idx => $value) {
- $list[$idx] = $value['displayname'];
-
- if (empty($list[$idx])) {
- $list[$idx] = $value['cn'];
- }
-
- if (!empty($value['mail'])) {
- $list[$idx] .= ' <' . $value['mail'] . '>';
- }
- }
-
- return $list;
+ return $this->_list_options_members($postdata, $attribs);
}
private function select_options_c($postdata, $attribs = array())
@@ -715,4 +682,48 @@ class kolab_api_service_form_value extends kolab_api_service
return $result;
}
}
+
+ private function _list_options_members($postdata, $attribs = array())
+ {
+ $service = $this->controller->get_service('users');
+
+ $keyword = array('value' => $postdata['search']);
+ $data = array(
+ 'attributes' => array('displayname', 'cn', 'mail'),
+ 'page_size' => 15,
+ 'search' => array(
+ 'displayname' => $keyword,
+ 'cn' => $keyword,
+ 'mail' => $keyword,
+ ),
+ );
+
+ $result = $service->users_list(null, $data);
+
+ $list = $result['list'];
+
+ $service = $this->controller->get_service('groups');
+ $data['attributes'] = array('cn', 'mail');
+
+ $result = $service->groups_list(null, $data);
+ $list = array_merge($list, $result['list']);
+
+ // convert to key=>value array
+ foreach ($list as $idx => $value) {
+ if (!empty($value['displayname'])) {
+ $list[$idx] = $value['displayname'];
+ } elseif (!empty($value['cn'])) {
+ $list[$idx] = $value['cn'];
+ } else {
+ console("No display name or cn for $idx");
+ }
+
+ if (!empty($value['mail'])) {
+ $list[$idx] .= ' <' . $value['mail'] . '>';
+ }
+ }
+
+ return $list;
+ }
+
}
diff --git a/lib/api/kolab_api_service_group.php b/lib/api/kolab_api_service_group.php
index f5e87ed..6e53340 100644
--- a/lib/api/kolab_api_service_group.php
+++ b/lib/api/kolab_api_service_group.php
@@ -132,6 +132,13 @@ class kolab_api_service_group extends kolab_api_service
return false;
}
+ public function group_effective_rights($getdata, $postdata)
+ {
+ $auth = Auth::get_instance();
+ $effective_rights = $auth->list_rights($getdata['group']);
+ return $effective_rights;
+ }
+
/**
* Group information.
*
@@ -152,8 +159,6 @@ class kolab_api_service_group extends kolab_api_service
// normalize result
$result = $this->parse_result_attributes('group', $result);
- //console("group_info() \$result", $result);
-
if ($result) {
return $result;
}
@@ -174,9 +179,10 @@ class kolab_api_service_group extends kolab_api_service
$auth = Auth::get_instance();
if (empty($getdata['group'])) {
- //error_log("Empty \$getdata['group']");
+ error_log("Empty \$getdata['group']");
return FALSE;
}
+
$result = $auth->group_members_list($getdata['group'], false);
return array(
diff --git a/lib/api/kolab_api_service_user.php b/lib/api/kolab_api_service_user.php
index ee4dd11..67e7e53 100644
--- a/lib/api/kolab_api_service_user.php
+++ b/lib/api/kolab_api_service_user.php
@@ -41,7 +41,7 @@ class kolab_api_service_user extends kolab_api_service
$auth = Auth::get_instance();
- $effective_rights = $auth->list_rights('group');
+ $effective_rights = $auth->list_rights('user');
//console("effective_rights", $effective_rights);
diff --git a/lib/client/kolab_client_task_group.php b/lib/client/kolab_client_task_group.php
index 5816408..d014a21 100644
--- a/lib/client/kolab_client_task_group.php
+++ b/lib/client/kolab_client_task_group.php
@@ -207,6 +207,7 @@ class kolab_client_task_group extends kolab_client_task
'cn' => 'system',
'gidnumber' => 'system',
'mail' => 'system',
+ 'member' => 'system',
'uniquemember' => 'system',
'memberurl' => 'system',
);
@@ -280,7 +281,14 @@ class kolab_client_task_group extends kolab_client_task
{
// convert to key=>value array, see kolab_api_service_form_value::list_options_uniquemember()
foreach ($list as $idx => $value) {
- $list[$idx] = $value['displayname'];
+ if (!empty($value['displayname'])) {
+ $list[$idx] = $value['displayname'];
+ } elseif (!empty($value['cn'])) {
+ $list[$idx] = $value['cn'];
+ } else {
+ console("No display name or cn for $idx");
+ }
+
if (!empty($value['mail'])) {
$list[$idx] .= ' <' . $value['mail'] . '>';
}
diff --git a/lib/kolab_client_task.php b/lib/kolab_client_task.php
index 4ccb5a4..7f14df4 100644
--- a/lib/kolab_client_task.php
+++ b/lib/kolab_client_task.php
@@ -851,7 +851,7 @@ class kolab_client_task
}
// Get the rights on the entry and attribute level
- $result = $this->api->get("user.effective_rights", array($name => $data['id']));
+ $result = $this->api->get($name . ".effective_rights", array($name => $data['id']));
$attribute_rights = $result->get('attributeLevelRights');
$entry_rights = $result->get('entryLevelRights');
diff --git a/lib/locale/en_US.php b/lib/locale/en_US.php
index 80d7092..0478581 100644
--- a/lib/locale/en_US.php
+++ b/lib/locale/en_US.php
@@ -114,6 +114,7 @@ $LANG['user.loginshell'] = 'Shell';
$LANG['user.uidnumber'] = 'User ID number';
$LANG['group.add'] = 'Add Group';
+$LANG['group.member'] = 'Member(s)';
$LANG['group.norecords'] = 'No group records found!';
$LANG['group.list'] = 'Groups List';
$LANG['group.list.records'] = '$1 to $2 of $3';
diff --git a/public_html/js/kolab_admin.js b/public_html/js/kolab_admin.js
index 0a73bde..d37c011 100644
--- a/public_html/js/kolab_admin.js
+++ b/public_html/js/kolab_admin.js
@@ -1002,7 +1002,7 @@ function kolab_admin()
is_empty = 0;
if ($.isArray(data[n]))
- is_empty = data[n].length;
+ is_empty = (data[n].length == 0) ? 1 : 0;
else
is_empty = !data[n];