summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: f12547c)
raw | patch | inline | side by side (parent: f12547c)
author | cajus <cajus@594d385d-05f5-0310-b6e9-bd551577e9d8> | |
Mon, 5 Oct 2009 11:27:37 +0000 (11:27 +0000) | ||
committer | cajus <cajus@594d385d-05f5-0310-b6e9-bd551577e9d8> | |
Mon, 5 Oct 2009 11:27:37 +0000 (11:27 +0000) |
git-svn-id: https://oss.gonicus.de/repositories/gosa/trunk@14509 594d385d-05f5-0310-b6e9-bd551577e9d8
index da8283fb786026841a8662bf22ba3f8f50ae5e66..185c9efc6f718947be695b1441e341d5d3449ca3 100644 (file)
definition below.
.PP
+.B idAllocationMethod
+.I traditional/pool
+.PP
+The
+.I idAllocationMethod
+statement defines how GOsa generates numeric user and group id values. If it is set to
+.I traditional
+GOsa will do create a lock and perform a search for the next free ID. The lock will be
+removed after the procedure completes.
+.I pool
+will use the sambaUnixIdPool objectclass settings inside your LDAP. This one is unsafe,
+because it does not check for concurrent LDAP access and already used IDs in this range.
+On the other hand it is much faster.
+.PP
+
.B minId
.I integer
.PP
The
.I minId
statement defines the minimum assignable user or group id to avoid security leaks with
-uid 0 accounts.
+uid 0 accounts. This is used for the
+.I traditional
+method
+.PP
+
+.B uidPoolMin/gidPoolMin
+.I integer
+.PP
+The
+.I uidPoolMin/gidPoolMin
+statement defines the minimum assignable user/group id for use with the
+.I pool
+method.
+.PP
+
+.B uidPoolMax/gidPoolMax
+.I integer
+.PP
+The
+.I uidPoolMin/gidPoolMin
+statement defines the highest assignable user/group id for use with the
+.I pool
+method.
.PP
.B nextIdHook
index 29f82e7fcd4e460a4c7f41dc04c0aa81695cb9b6..3bcf7f410dca6fad7a1bee1610ebda6c0eaccfa1 100644 (file)
if ($dn == "")
$dn = $this->basedn;
- $r = @ldap_mod_del($this->cid, LDAP::fix($dn), $attrs);
+ $r = ldap_mod_del($this->cid, LDAP::fix($dn), $attrs);
+ $this->error = @ldap_error($this->cid);
+ return($r);
+ }else{
+ $this->error = "Could not connect to LDAP server";
+ return("");
+ }
+ }
+
+ function mod_add($attrs = "", $dn = "")
+ {
+ if($this->hascon){
+ if ($this->reconnect) $this->connect();
+ if ($dn == "")
+ $dn = $this->basedn;
+
+ $r = @ldap_mod_add($this->cid, LDAP::fix($dn), $attrs);
$this->error = @ldap_error($this->cid);
return($r);
}else{
index c09a59acf896815a5d55d8a12754e2fd47275bef..48bf1b87130c5f83763b4f82ae0f0cff25651520 100644 (file)
}
+function get_next_id($attrib, $dn)
+{
+ global $config;
+
+ switch ($config->get_cfg_value("idAllocationMethod", "traditional")){
+ case "pool":
+ return get_next_id_pool($attrib);
+ case "traditional":
+ return get_next_id_traditional($attrib, $dn);
+ }
+
+ msg_dialog::display(_("Error"), _("Cannot allocate a free ID:")." "._("unknown idAllocation method!"), ERROR_DIALOG);
+ return null;
+}
+
+
+function get_next_id_pool($attrib) {
+ global $config;
+
+ /* Fill informational values */
+ $min= $config->get_cfg_value("${attrib}PoolMin", 10000);
+ $max= $config->get_cfg_value("${attrib}PoolMax", 40000);
+
+ /* Sanity check */
+ if ($min >= $max) {
+ msg_dialog::display(_("Error"), _("Cannot allocate a free ID:")." ".sprintf(_("%sPoolMin >= %sPoolMax!"), $attrib), ERROR_DIALOG);
+ return null;
+ }
+
+ /* ID to skip */
+ $ldap= $config->get_ldap_link();
+ $id= null;
+
+ /* Try to allocate the ID several times before failing */
+ $tries= 3;
+ while ($tries--) {
+
+ /* Look for ID map entry */
+ $ldap->cd ($config->current['BASE']);
+ $ldap->search ("(&(objectClass=sambaUnixIdPool)($attrib=*))", array("$attrib"));
+
+ /* If it does not exist, create one with these defaults */
+ if ($ldap->count() == 0) {
+ /* Fill informational values */
+ $minUserId= $config->get_cfg_value("uidPoolMin", 10000);
+ $minGroupId= $config->get_cfg_value("gidPoolMin", 10000);
+
+ /* Add as default */
+ $attrs= array("objectClass" => array("organizationalUnit", "sambaUnixIdPool"));
+ $attrs["ou"]= "idmap";
+ $attrs["uidNumber"]= $minUserId;
+ $attrs["gidNumber"]= $minGroupId;
+ $ldap->cd("ou=idmap,".$config->current['BASE']);
+ $ldap->add($attrs);
+ if ($ldap->error != "Success") {
+ msg_dialog::display(_("Error"), _("Cannot create sambaUnixIdPool entry!"), ERROR_DIALOG);
+ return null;
+ }
+ $tries++;
+ continue;
+ }
+ /* Bail out if it's not unique */
+ if ($ldap->count() != 1) {
+ msg_dialog::display(_("Error"), _("Cannot allocate a free ID:")." "._("sambaUnixIdPool is not unique!"), ERROR_DIALOG);
+ return null;
+ }
+
+ /* Store old attrib and generate new */
+ $attrs= $ldap->fetch();
+ $dn= $ldap->getDN();
+ $oldAttr= $attrs[$attrib][0];
+ $newAttr= $oldAttr + 1;
+
+ /* Sanity check */
+ if ($newAttr >= $max) {
+ msg_dialog::display(_("Error"), _("Cannot allocate a free ID:")." "._("no ID available!"), ERROR_DIALOG);
+ return null;
+ }
+ if ($newAttr < $min) {
+ msg_dialog::display(_("Error"), _("Cannot allocate a free ID:")." "._("no ID available!"), ERROR_DIALOG);
+ return null;
+ }
+
+ #FIXME: PHP is not able to do a modification of "del: .../add: ...", so this
+ # is completely unsafe in the moment.
+ #/* Remove old attr, add new attr */
+ #$attrs= array($attrib => $oldAttr);
+ #$ldap->rm($attrs, $dn);
+ #if ($ldap->error != "Success") {
+ # continue;
+ #}
+ $ldap->cd($dn);
+ $ldap->modify(array($attrib => $newAttr));
+ if ($ldap->error != "Success") {
+ msg_dialog::display(_("Error"), _("Cannot allocate a free ID:")." ".$ldap->get_error(), ERROR_DIALOG);
+ return null;
+ } else {
+ return $newAttr;
+ }
+ }
+
+ /* Bail out if we had problems getting the next id */
+ if (!$tries) {
+ msg_dialog::display(_("Error"), _("Cannot allocate a free ID:")." "._("maximum tries exceeded!"), ERROR_DIALOG);
+ }
+
+ return $id;
+}
+
+function get_next_id_traditional($attrib, $dn)
+{
+ global $config;
+
+ $ids= array();
+ $ldap= $config->get_ldap_link();
+
+ $ldap->cd ($config->current['BASE']);
+ if (preg_match('/gidNumber/i', $attrib)){
+ $oc= "posixGroup";
+ } else {
+ $oc= "posixAccount";
+ }
+ $ldap->search ("(&(objectClass=$oc)($attrib=*))", array("$attrib"));
+
+ /* Get list of ids */
+ while ($attrs= $ldap->fetch()){
+ $ids[]= (int)$attrs["$attrib"][0];
+ }
+
+ /* Add the nobody id */
+ $ids[]= 65534;
+
+ /* get the ranges */
+ $tmp = array('0'=> 1000);
+ if (preg_match('/posixAccount/', $oc) && $config->get_cfg_value("uidNumberBase") != ""){
+ $tmp= split('-',$config->get_cfg_value("uidNumberBase"));
+ } elseif($config->get_cfg_value("gidNumberBase") != ""){
+ $tmp= split('-',$config->get_cfg_value("gidNumberBase"));
+ }
+
+ /* Set hwm to max if not set - for backward compatibility */
+ $lwm= $tmp[0];
+ if (isset($tmp[1])){
+ $hwm= $tmp[1];
+ } else {
+ $hwm= pow(2,32);
+ }
+ /* Find out next free id near to UID_BASE */
+ if ($config->get_cfg_value("baseIdHook") == ""){
+ $base= $lwm;
+ } else {
+ /* Call base hook */
+ $base= get_base_from_hook($dn, $attrib);
+ }
+ for ($id= $base; $id++; $id < pow(2,32)){
+ if (!in_array($id, $ids)){
+ return ($id);
+ }
+ }
+
+ /* Should not happen */
+ if ($id == $hwm){
+ msg_dialog::display(_("Error"), _("Cannot allocate a free ID!"), ERROR_DIALOG);
+ exit;
+ }
+}
+
+
// vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
?>
diff --git a/gosa-core/plugins/admin/groups/class_groupGeneric.inc b/gosa-core/plugins/admin/groups/class_groupGeneric.inc
index 0cf314a07203b693983543b205635f2de7bd62c1..5c9e62da6a87754a386127479926b361e153d434 100644 (file)
}
}
add_lock ("gidnumber", "gosa");
- $this->gidNumber= $this->get_next_id("gidNumber", $this->dn);
+ $this->gidNumber= get_next_id("gidNumber", $this->dn);
}
}
return ($message);
}
- function get_next_id($attrib, $dn)
- {
- $ids= array();
- $ldap= $this->config->get_ldap_link();
-
- $ldap->cd ($this->config->current['BASE']);
- if (preg_match('/gidNumber/i', $attrib)){
- $oc= "posixGroup";
- $att= "gidNumberBase";
- } else {
- $oc= "posixAccount";
- $att= "uidNumberBase";
- }
- $ldap->search ("(&(objectClass=$oc)($attrib=*))", array("$attrib"));
-
- /* Get list of ids */
- while ($attrs= $ldap->fetch()){
- $ids[]= (int)$attrs["$attrib"][0];
- }
-
- /* Find out next free id near to UID_BASE */
- if ($this->config->get_cfg_value("baseIdHook") == ""){
- $base= $this->config->get_cfg_value($att);
- } else {
- /* Call base hook */
- $base= get_base_from_hook($dn, $attrib);
- }
- for ($id= $base; $id++; $id < pow(2,32)){
- if (!in_array($id, $ids)){
- return ($id);
- }
- }
-
- /* Check if id reached maximum */
- if ($id >= pow(2,32)){
- msg_dialog::display(_("Error"), _("Cannot allocate a free ID!"), ERROR_DIALOG);
- exit;
- }
- }
function getCopyDialog()
{
diff --git a/gosa-core/plugins/personal/posix/class_posixAccount.inc b/gosa-core/plugins/personal/posix/class_posixAccount.inc
index 1ea0509e950cdbf38401676fd65b663a07ecb60d..ccb54c03ee71be7eb17bca17611cd8b7a0f4c2d3 100644 (file)
}
}
add_lock ("uidnumber", "gosa");
- $this->uidNumber= $this->get_next_id("uidNumber", $this->dn);
+ $this->uidNumber= get_next_id("uidNumber", $this->dn);
}
}
/* Request a new and uniqe gidNumber, if required */
if(!$this->force_ids){
- $this->gidNumber= $this->get_next_id("gidNumber", $this->dn);
+ $this->gidNumber= get_next_id("gidNumber", $this->dn);
}else{
/* If forced gidNumber could not be found, then check if the given group name already exists
}
- function get_next_id_new($attrib, $dn)
- {
- /* ID to skip */
- $nobody= 65534;
-
- # again:
- # Look for ID map entry (objectClass=sambaUnixIdPool)
-
- # If it does not exist, create one with these defaults
- #dn: ou=idmap,$BASE
- #objectClass: organizationalUnit
- #objectClass: sambaUnixIdPool
- #ou: idmap
- #uidNumber: $minId
- #gidNumber: $minId
-
- # Take $attrib, modify it to [$attrib] + 1
- # -> if $attrib does not exist -> bail out
- # -> if this works, return [$attrib]
- # -> if this does not work: goto again for max 3 times
- # -> if this fails -> bail out
- }
-
-
- function get_next_id($attrib, $dn)
- {
- $ids= array();
- $ldap= $this->config->get_ldap_link();
-
- $ldap->cd ($this->config->current['BASE']);
- if (preg_match('/gidNumber/i', $attrib)){
- $oc= "posixGroup";
- } else {
- $oc= "posixAccount";
- }
- $ldap->search ("(&(objectClass=$oc)($attrib=*))", array("$attrib"));
-
- /* Get list of ids */
- while ($attrs= $ldap->fetch()){
- $ids[]= (int)$attrs["$attrib"][0];
- }
-
- /* Add the nobody id */
- $ids[]= 65534;
-
- /* get the ranges */
- $tmp = array('0'=> 1000);
- if (preg_match('/posixAccount/', $oc) && $this->config->get_cfg_value("uidNumberBase") != ""){
- $tmp= split('-',$this->config->get_cfg_value("uidNumberBase"));
- } elseif($this->config->get_cfg_value("gidNumberBase") != ""){
- $tmp= split('-',$this->config->get_cfg_value("gidNumberBase"));
- }
-
- /* Set hwm to max if not set - for backward compatibility */
- $lwm= $tmp[0];
- if (isset($tmp[1])){
- $hwm= $tmp[1];
- } else {
- $hwm= pow(2,32);
- }
-
- /* Find out next free id near to UID_BASE */
- if ($this->config->get_cfg_value("baseIdHook") == ""){
- $base= $lwm;
- } else {
- /* Call base hook */
- $base= get_base_from_hook($dn, $attrib);
- }
- for ($id= $base; $id++; $id < pow(2,32)){
- if (!in_array($id, $ids)){
- return ($id);
- }
- }
-
- /* Should not happen */
- if ($id == $hwm){
- msg_dialog::display(_("Error"), _("Cannot allocate a free ID!"), ERROR_DIALOG);
- exit;
- }
- }
-
-
function reload()
{
/* Set base for all searches */
/* Avoid using the same gid/uid number as source user
empty numbers to enforce new ones. */
-# $this->savedUidNumber = $this->get_next_id("uidNumber", $this->dn);
+# $this->savedUidNumber = $get_next_id("uidNumber", $this->dn);
$this->savedUidNumber = "";
-# $this->savedGidNumber = $this->get_next_id("gidNumber", $this->dn);
+# $this->savedGidNumber = $get_next_id("gidNumber", $this->dn);
$this->savedGidNumber = "";
/* Get group membership */