summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 8c98578)
raw | patch | inline | side by side (parent: 8c98578)
author | cajus <cajus@594d385d-05f5-0310-b6e9-bd551577e9d8> | |
Fri, 28 May 2010 16:10:55 +0000 (16:10 +0000) | ||
committer | cajus <cajus@594d385d-05f5-0310-b6e9-bd551577e9d8> | |
Fri, 28 May 2010 16:10:55 +0000 (16:10 +0000) |
git-svn-id: https://oss.gonicus.de/repositories/gosa/trunk@18796 594d385d-05f5-0310-b6e9-bd551577e9d8
gosa-plugins/dyngroup/README | [new file with mode: 0644] | patch | blob |
gosa-plugins/dyngroup/plugin.dsc | [new file with mode: 0644] | patch | blob |
gosa-plugins/dyngroup/plugins/addons/dyngroup/classDynamicLdapGroup.inc | [new file with mode: 0644] | patch | blob |
gosa-plugins/dyngroup/plugins/addons/dyngroup/dyngroup.tpl | [new file with mode: 0644] | patch | blob |
gosa-plugins/dyngroup/schema/gosa-dyngroup.schema | [new file with mode: 0644] | patch | blob |
gosa-plugins/dyngroup/schema/gosa-samba3.schema.patch | [new file with mode: 0644] | patch | blob |
diff --git a/gosa-plugins/dyngroup/README b/gosa-plugins/dyngroup/README
--- /dev/null
@@ -0,0 +1,100 @@
+# ----------------------------------------------------------------------------- #
+# README #
+# Author(s): Thomas Chemineau - thomas.chemineau<at>gmail.com #
+# ----------------------------------------------------------------------------- #
+
+
+1. What this plugin can do ?
+
+ This plugin allow administrator to modify LDAP groups to be populated through
+ dynamic list feature in OpenLDAP.
+
+ To do that, you have to activate the dynlist overlay in OpenLDAP, and
+ configure the overlay as decribed bellow. Once the overlay is enabled, member
+ of a dynamic group will be auto populated.
+
+ This plugin should be configured to appears in groups and departments, under
+ GOsa. A department could not be a dynamic group, but it can be renamed. This
+ operation could break LDAP search URLs into dynamic group definition. To
+ prevent this, this plugin could modify LDAP search URLs when departments and
+ groups are renamed into the LDAP tree.
+
+ WARNINGS:
+ Be carefull, GOsa may manage uid into memberUid, and not DN. So, in this
+ particular case, you can not store DN into memberUid attribute. The main
+ drawback, in this particular case, is that you can not build LDAP URLs into
+ dynamic group to search for users directly. The alternative is to look for
+ memberUid into groups.
+
+
+2. How to activate the dynlist overlay in OpenLDAP ?
+
+ Edit the configuration file (slapd.conf), and put the following lines into
+ the definition of your database:
+
+ overlay dynlist
+ dynlist-attrset gosaGroupOfURLs labeledURI
+
+ See http://www.openldap.org/doc/admin24/overlays.html#Dynamic%20Lists to have
+ more informations on dynamic list overlay.
+
+ If your OpenLDAP server loads modules dnamically, you have to load the
+ dynlist overlay but putting the following lines in the global section of the
+ configuration files:
+
+ moduleload dynlist
+
+ Finaly, if you do not want GOsa users to modify memberUid values, you could
+ add an ACL. This ACL will works only if GOsa is connected on your OpenLDAP
+ server under an application account (and not under the rootdn defined into
+ the configuration of your LDAP database in slapd.conf):
+
+ # Disable modify on memberUid for all entries which contains
+ # gosaGroupOfURLs, because these are dynamic, and we do not want users to
+ # edit the memberUid attribute.
+ access to filter="objectClass=gosaGroupOfURLs" attrs=memberUid
+ by * read
+
+ Verify that LDAP schemas of GOsa contains the definition of the objectclass
+ named "gosaGroupOfURLs". You have two solutions: the first one is to add it
+ into the schema named gosa-samba3:
+
+ objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.21
+ NAME 'gosaGroupOfURLs'
+ DESC 'Allow a group to be populated through a labeledURI values'
+ SUP top
+ AUXILIARY
+ MAY ( labeledURI ) )
+
+ The second one, recommended, is to copy the file gosa-dyngroup.schema into
+ your OpenLDAP schema directory. Then edit slapd.conf and add the inclusion
+ to this new schema.
+
+ You can now restart your OpenLDAP server :)
+
+
+3. How to enable this feature in GOsa ?
+
+ It is very easy. Edit /etc/gosa/gosa.conf, and add the following line in
+ the grouptabs section:
+
+ <tab class="DynamicLdapGroup" name="Dynamic group" />
+
+ Then, add the following line in the deptabs section:
+
+ <tab class="DynamicLdapGroup" name="Dynamic group" />
+
+ Then, put the plugin in /usr/share/gosa/plugins/addons, and update GOsa cache
+ via the update-gosa command.
+
+
+4. Known restrictions in OpenLDAP
+
+ You can't search yet on memberUid in a filter:
+ http://www.openldap.org/lists/openldap-software/200812/msg00030.html
+ http://www.openldap.org/lists/openldap-software/200901/msg00079.html
+
+ You have to prefer to use the LDAP compare operation:
+ http://www.openldap.org/lists/openldap-software/200909/msg00073.html
+ http://www.openldap.org/lists/openldap-software/200909/msg00125.html
+
diff --git a/gosa-plugins/dyngroup/plugin.dsc b/gosa-plugins/dyngroup/plugin.dsc
--- /dev/null
@@ -0,0 +1,8 @@
+[gosa-plugin]
+name = dyngroup
+description = "dynamic group list feature in OpenLDAP"
+version = 2.6.7
+author = "Thomas Chemineau - thomas.chemineau@gmail.com"
+maintainer = "GOsa packages maintainers group <gosa-pkg@oss.gonicus.de>"
+homepage = https://oss.gonicus.de/labs/gosa-contrib/
+
diff --git a/gosa-plugins/dyngroup/plugins/addons/dyngroup/classDynamicLdapGroup.inc b/gosa-plugins/dyngroup/plugins/addons/dyngroup/classDynamicLdapGroup.inc
--- /dev/null
@@ -0,0 +1,365 @@
+<?php
+
+/*
+ * This code is part of GOsa (http://www.gosa-project.org)
+ * Copyright (C) 2003-2008 GONICUS GmbH
+ * Copyright (C) 2010 Thomas CHEMINEAU
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/**
+ * This class will allow user to parameter dynamic group.
+ * @author Thomas Chemineau - thomas.chemineau<at>gmail.com
+ * @version 0.01
+ */
+class DynamicLdapGroup extends group
+{
+
+ /**
+ * The attribute that will use GOsa to store LDAP URI.
+ * @var array
+ */
+ public $attributes = array('labeledURI');
+
+ /**
+ * The objectClass that will use GOsa to identify a group as dynamic.
+ * @var array
+ */
+ public $objectclasses = array('labeledURIObject');
+
+ /**
+ * Default value for the corresponding attribute found in the $this->attributes
+ * array of this plugin.
+ * @var string
+ */
+ public $labeledURI = 'ldap:///dc=example,dc=com?memberUid?sub?(objectClass=posixGroup)';
+
+ /**
+ * Indicates if the feature is enabled or not.
+ * @var boolean
+ */
+ private $_isEnabled = false;
+
+ /**
+ * Indicates if this plugin is manualy activated.
+ * @var boolean
+ */
+ private $_isManualyActivated = false;
+
+ /**
+ * Store values of memberUrl.
+ * @var Array
+ */
+ private $_memberUrls = Array();
+
+ /**
+ * Create this object.
+ * @param Array $config GOsa config.
+ * @param string $dn Current DN.
+ */
+ public function __construct ($config, $dn)
+ {
+ parent::__construct($config, $dn);
+ $attr_label = $this->attributes[0];
+ $this->$attr_label = str_replace('dc=example,dc=com', $this->dn, $this->$attr_label);
+ }
+
+ /**
+ * This function is called by GOsa when the current group will be saved into the
+ * LDAP directory. It will check status of this plugin.
+ */
+ public function check ()
+ {
+ if (!$this->_isManualyActivated)
+ {
+ $this->_isEnabled = $this->isDynamicGroup();
+ }
+ return Array();
+ }
+
+ /**
+ * Execute this plugin.
+ * @return string HTML to print.
+ */
+ public function execute ()
+ {
+ //
+ // Are we trying to modify state of this group ? If so,
+ // we can edit the current object.
+ //
+ if (isset($_POST['modify_state']))
+ {
+ $this->_isEnabled = !$this->_isEnabled;
+ $this->_isManualyActivated = true;
+ }
+ //
+ // Found if this group is dynamic or not. If it is not dynamic,
+ // we propose to enable this feature on this group. But by default,
+ // we mark this feature disabled.
+ //
+ $this->check();
+ //
+ // Display a message if this feature is disabled.
+ //
+ if (!$this->_isEnabled)
+ {
+ return $this->show_disable_header(msgPool::addFeaturesButton(_("Dynamic Group")), msgPool::featuresDisabled(_("Dynamic Group")));
+ }
+ $display = $this->show_disable_header(msgPool::removeFeaturesButton(_("Dynamic Group")), msgPool::featuresEnabled(_("Dynamic Group")));
+ //
+ // Now, we search for current attributes, and display them.
+ //
+ $this->save_object();
+ $attr_label = $this->attributes[0];
+ $attr_value = $this->$attr_label;
+ // Display values.
+ //
+ $smarty = get_smarty();
+ $smarty->assign('memberURLAttributeLabel', $attr_label);
+ $smarty->assign('memberURLAttributeValue', $attr_value);
+ $display .= $smarty->fetch(get_template_path('dyngroup.tpl', TRUE, dirname(__FILE__)));
+ return $display;
+ }
+
+ /**
+ * Return attributes values of an LDAP entry.
+ * @param String $dn DN of the LDAP entry.
+ * @param Array $attributes Attributes to look for.
+ * @return Array An associative array of requested values.
+ */
+ public function getAttributesValues ($dn, $attributes = Array('dn'))
+ {
+ $ldap = $this->config->get_ldap_link();
+ $ldap->cat($dn, $attributes);
+ if ($attrs = $ldap->fetch())
+ {
+ $data = Array();
+ foreach ($attributes as $attribute)
+ {
+ if (array_key_exists($attribute, $attrs) !== false)
+ {
+ $data[$attribute] = $attrs[$attribute];
+ unset($data[$attribute]['count']);
+ }
+ }
+ if (sizeof($data) > 0)
+ {
+ return $data;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Test if the current group is dynamic or not.
+ * The more simple way is to test if the objectclass exists into
+ * the entry.
+ * @return boolean True if this entry is considered as dynamic.
+ */
+ public function isDynamicGroup ()
+ {
+ $obj_ocs = $this->getAttributesValues($this->dn, Array('objectClass'));
+ if ($obj_ocs === false)
+ {
+ return false;
+ }
+ $obj_ocs = array_map('strtolower', $obj_ocs['objectClass']);
+ $plu_ocs = $this->objectclasses;
+ $plu_ocs_size = sizeof($this->objectclasses);
+ $found = 0;
+ for ($i=0; $i<$plu_ocs_size && $found<$plu_ocs_size; $i++)
+ {
+ $plu_oc = strtolower($plu_ocs[$i]);
+ if (in_array($plu_oc, $obj_ocs))
+ {
+ $found++;
+ }
+ }
+ if ($found >= $plu_ocs_size)
+ {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Static method to set ACL for this plugin.
+ */
+ public static function plInfo()
+ {
+ return Array(
+ "plShortName" => _("dyngroup"),
+ "plDescription" => _("Dynamic group setting"),
+ "plSelfModify" => TRUE,
+ "plDepends" => Array(),
+ "plPriority" => 1,
+ "plSection" => Array("addon"),
+ "plCategory" => Array(
+ "groups" => Array(
+ "description" => _("Dynamic Groups"),
+ "objectClass" => "labeledURIObject"
+ )
+ ),
+ "plProvidedAcls" => array(
+ 'labeledURI' => _('labeledURI'),
+ )
+ );
+ }
+
+ /**
+ * This plugin does nothing when this method is invoked.
+ */
+ public function remove_from_parent ()
+ {
+ return;
+ }
+
+ /**
+ * Modify search base for all URL of all dynamic groups objects into the LDAP
+ * directory.
+ */
+ public function renameDNsInDynGroupsValues ($old_dn, $new_dn)
+ {
+ $ldap = $this->config->get_ldap_link();
+ $ldap->cd($this->config->current['BASE']);
+ //
+ // Build the LDAP search filter. We take only LDAP entries which have all
+ // objectClasses and attributes defined by this plugin.
+ //
+ $filter = '';
+ foreach ($this->objectclasses as $objectclass)
+ {
+ $filter .= '(objectClass=' . $objectclass . ')';
+ }
+ foreach ($this->attributes as $attribute)
+ {
+ $filter .= '(' . $attribute . '=*)';
+ }
+ $filter = '(&' . $filter . ')';
+ //
+ // The search should return some LDAP entries. If so, performed modifications
+ // on values (delete the values, and add it again with correct search DN).
+ //
+ $ldap->search($filter, Array('dn'));
+ if ($attrs = $ldap->fetch())
+ {
+ foreach ($attrs as $dn)
+ {
+ $values = $this->getAttributesValues($dn, $this->attributes);
+ if ($values === false || !is_array($values))
+ {
+ continue;
+ }
+ foreach ($values as $attribute => $value)
+ {
+ for($i=0; $i<sizeof($value); $i++)
+ {
+ $values[$attribute][$i] = str_replace($old_dn, $new_dn, $values[$attribute][$i]);
+ }
+ }
+ $ldap->cd($dn);
+ $ldap->modify($values);
+ }
+ }
+ }
+
+ /**
+ * This function is called when tab is undisplayed. For example, the current user
+ * wants to change other settings of this group, but not save it to the LDAP
+ * directory directly.
+ */
+ public function save_object ()
+ {
+ $cur_memberURLLabel = $this->attributes[0];
+ $cur_memberURLValue = null;
+ if (isset($_POST[$cur_memberURLLabel]))
+ {
+ $cur_memberURLValue = $_POST[$cur_memberURLLabel];
+ $this->_isManualyActivated = true;
+ }
+ else if (!$this->_isManualyActivated)
+ {
+ $obj_memberURLValue = $this->getAttributesValues($this->dn, $this->attributes);
+ if ($obj_memberURLValue !== false)
+ {
+ $cur_memberURLValue = $obj_memberURLValue[$cur_memberURLLabel];
+ }
+ }
+ if (!is_null($cur_memberURLValue))
+ {
+ $this->$cur_memberURLLabel = $cur_memberURLValue;
+ }
+ }
+
+ /**
+ * That will add additionnal information into the current LDAP entry.
+ * If this plugin is disable, then it will remove any data that references
+ * this plugin into the LDAP directory.
+ * @return boolean
+ */
+ public function save ()
+ {
+ $ldap = $this->config->get_ldap_link();
+ $ldap->cd($this->dn);
+ //
+ // We disable dynamic group feature for this group, when:
+ // - The feature should be disable and this group is not dynamic;
+ // - The attributes exists into the entry.
+ //
+ if (!$this->_isEnabled && $this->isDynamicGroup())
+ {
+ if (array_key_exists($this->attributes[0], $this->attrs) !== false)
+ {
+ $data = Array(
+ $this->attributes[0] => Array()
+ );
+ $ldap->modify($data);
+ }
+ $data = Array(
+ 'objectClass' => $this->objectclasses
+ );
+ $ldap->rm($data);
+ }
+ //
+ // GOsa auto update $this->$attributeLabel with data found into
+ // forms. So, existing data will be saved, without doing anything.
+ // The operation is already done, no checks.
+ //
+ else if ($this->_isEnabled)
+ {
+ $data = Array(
+ 'objectClass' => $this->objectclasses
+ );
+ $ldap->mod_add($data);
+ $attributeLabel = $this->attributes[0];
+ $data = Array(
+ $this->attributes[0] => Array($this->$attributeLabel)
+ );
+ $ldap->modify($data);
+ }
+ //
+ // Detect if the current entry is renamed. If so, search for all
+ // dynamic groups, and modify search basedn if necessary.
+ //
+ if (strcasecmp($this->orig_dn, $this->dn) != 0)
+ {
+ $this->renameDNsInDynGroupsValues($this->orig_dn, $this->dn);
+ }
+ }
+
+}
+
+?>
diff --git a/gosa-plugins/dyngroup/plugins/addons/dyngroup/dyngroup.tpl b/gosa-plugins/dyngroup/plugins/addons/dyngroup/dyngroup.tpl
--- /dev/null
@@ -0,0 +1,17 @@
+<table summary="" style="width:100%; vertical-align:top; text-align:left;" cellpadding="0" border="0">
+ <tr>
+ <td style="width:100%; vertical-align:top;">
+ <h2><img class="center" alt="" align="middle" src="images/rightarrow.png" /> {t}Generic{/t}</h2>
+ <table summary="">
+ <tr>
+ <td><label for="{$memberURLAttributeLabel}">{t}{$memberURLAttributeLabel}{/t}</label></td>
+ <td>
+ {foreach item=line from=$memberURLAttributeValue}
+ <input size=70 name="{$memberURLAttributeLabel}" value="{$line}">
+ {/foreach}
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+</table>
diff --git a/gosa-plugins/dyngroup/schema/gosa-dyngroup.schema b/gosa-plugins/dyngroup/schema/gosa-dyngroup.schema
--- /dev/null
@@ -0,0 +1,14 @@
+
+#
+# OpenLDAP schema to add gosaGroupOfURLs objectClass.
+# This objectClass is the same as defined by the OpenLDAP project, but it is
+# defined as AUXILIARY.
+#
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.21
+ NAME 'gosaGroupOfURLs'
+ DESC 'Allow a group to be populated through a labeledURI values'
+ SUP top
+ AUXILIARY
+ MAY ( labeledURI ) )
+
diff --git a/gosa-plugins/dyngroup/schema/gosa-samba3.schema.patch b/gosa-plugins/dyngroup/schema/gosa-samba3.schema.patch
--- /dev/null
@@ -0,0 +1,16 @@
+--- gosa-samba3.schema.old 2010-01-30 18:54:45.000000000 +0100
++++ gosa-samba3.schema 2010-01-30 16:29:10.000000000 +0100
+@@ -395,6 +395,13 @@
+ DESC 'Settings for gosa. Replaces parts of the gosa.conf. (v2.6)' SUP top STRUCTURAL
+ MAY ( gosaSetting ) )
+
++objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.21
++ NAME 'gosaGroupOfURLs'
++ DESC 'Allow a group to be populated through a labeledURI values'
++ SUP top
++ AUXILIARY
++ MAY ( labeledURI ) )
++
+ # GOto submenu entries
+ objectclass (1.3.6.1.4.1.10098.1.2.1.43 NAME 'gotoSubmenuEntry'
+ DESC 'GOto - contains environment settings (v2.6)' SUP top STRUCTURAL