Exemple #1
0
 /**
  * Write the entry or entries to the LDIF file.
  *
  * If you want to build an LDIF file containing several entries AND
  * you want to call write_entry() several times, you must open the filehandle
  * in append mode ("a"), otherwise you will always get the last entry only.
  *
  * @param Net_LDAP_Entry|array $entries Entry or array of entries
  *
  * @return void
  * @todo implement operations on whole entries (adding a whole entry)
  */
 function write_entry($entries)
 {
     if (!is_array($entries)) {
         $entries = array($entries);
     }
     foreach ($entries as $entry) {
         $this->_entrynum++;
         if (!is_a($entry, 'Net_LDAP_Entry')) {
             $this->_dropError('Net_LDAP_LDIF error: entry ' . $this->_entrynum . ' is not an Net_LDAP_Entry object');
         } else {
             if ($this->_options['change']) {
                 // LDIF change mode
                 // fetch change information from entry
                 $entry_attrs_changes = $entry->getChanges();
                 $num_of_changes = count($entry_attrs_changes['add']) + count($entry_attrs_changes['replace']) + count($entry_attrs_changes['delete']);
                 $is_changed = $num_of_changes > 0 || $entry->willBeDeleted() || $entry->willBeMoved();
                 // write version if not done yet
                 // also write DN of entry
                 if ($is_changed) {
                     if (!$this->_version_written) {
                         $this->write_version();
                     }
                     $this->_writeDN($entry->currentDN());
                 }
                 // process changes
                 // TODO: consider DN add!
                 if ($entry->willBeDeleted()) {
                     $this->_writeLine("changetype: delete" . PHP_EOL);
                 } elseif ($entry->willBeMoved()) {
                     $this->_writeLine("changetype: modrdn" . PHP_EOL);
                     $olddn = Net_LDAP_Util::ldap_explode_dn($entry->currentDN(), array('casefold' => 'none'));
                     // maybe gives a bug if using multivalued RDNs
                     $oldrdn = array_shift($olddn);
                     $oldparent = implode(',', $olddn);
                     $newdn = Net_LDAP_Util::ldap_explode_dn($entry->dn(), array('casefold' => 'none'));
                     // maybe gives a bug if using multivalued RDNs
                     $rdn = array_shift($newdn);
                     $parent = implode(',', $newdn);
                     $this->_writeLine("newrdn: " . $rdn . PHP_EOL);
                     $this->_writeLine("deleteoldrdn: 1" . PHP_EOL);
                     if ($parent !== $oldparent) {
                         $this->_writeLine("newsuperior: " . $parent . PHP_EOL);
                     }
                     // TODO: What if the entry has attribute changes as well?
                     //       I think we should check for that and make a dummy
                     //       entry with the changes that is written to the LDIF file
                 } elseif ($num_of_changes > 0) {
                     // write attribute change data
                     $this->_writeLine("changetype: modify" . PHP_EOL);
                     foreach ($entry_attrs_changes as $changetype => $entry_attrs) {
                         foreach ($entry_attrs as $attr_name => $attr_values) {
                             $this->_writeLine("{$changetype}: {$attr_name}" . PHP_EOL);
                             if ($attr_values !== null) {
                                 $this->_writeAttribute($attr_name, $attr_values, $changetype);
                             }
                             $this->_writeLine("-" . PHP_EOL);
                         }
                     }
                 }
                 // finish this entrys data if we had changes
                 if ($is_changed) {
                     $this->_finishEntry();
                 }
             } else {
                 // LDIF-content mode
                 // fetch attributes for further processing
                 $entry_attrs = $entry->getValues();
                 // sort and put objectclass-attrs to first position
                 if ($this->_options['sort']) {
                     ksort($entry_attrs);
                     if (array_key_exists('objectclass', $entry_attrs)) {
                         $oc = $entry_attrs['objectclass'];
                         unset($entry_attrs['objectclass']);
                         $entry_attrs = array_merge(array('objectclass' => $oc), $entry_attrs);
                     }
                 }
                 // write data
                 if (!$this->_version_written) {
                     $this->write_version();
                 }
                 $this->_writeDN($entry->dn());
                 foreach ($entry_attrs as $attr_name => $attr_values) {
                     $this->_writeAttribute($attr_name, $attr_values);
                 }
                 $this->_finishEntry();
             }
         }
     }
 }
Exemple #2
0
 /**
  * Tell if a DN does exist in the directory
  *
  * @param string $dn The DN of the object to test
  *
  * @return boolean|Net_LDAP_Error
  */
 function dnExists($dn)
 {
     if (!is_string($dn)) {
         return PEAR::raiseError('$dn is expected to be a string but is ' . gettype($dn) . ' ' . get_class($dn));
     }
     // make dn relative to parent
     $base = Net_LDAP_Util::ldap_explode_dn($dn, array('casefold' => 'none', 'reverse' => false, 'onlyvalues' => false));
     if (Net_LDAP::isError($base)) {
         return $base;
     }
     $entry_rdn = array_shift($base);
     if (is_array($entry_rdn)) {
         // maybe the dn consist of a multivalued RDN, we must build the dn in this case
         // because the $entry_rdn is an array!
         $filter_dn = Net_LDAP_Util::canonical_dn($entry_rdn);
     }
     $base = Net_LDAP_Util::canonical_dn($base);
     $result = @ldap_list($this->_link, $base, $entry_rdn, array(), 1, 1);
     if (@ldap_count_entries($this->_link, $result)) {
         return true;
     }
     if (ldap_errno($this->_link) == 32) {
         return false;
     }
     if (ldap_errno($this->_link) != 0) {
         return PEAR::raiseError(ldap_error($this->_link), ldap_errno($this->_link));
     }
     return false;
 }
Exemple #3
0
 /**
  * Update the entry on the directory server
  *
  * @access public
  * @param Net_LDAP $ldap (optional) If you provide a Net_LDAP object, be sure to PASS IT VIA REFERENCE!
  * @return true|Net_LDAP_Error
  * @todo Entry rename with a DN containing special characters needs testing!
  */
 function update($ldap = false)
 {
     if (!$ldap) {
         // If object is not provided, then use this entrys ldap object
         $ldap =& $this->_ldap;
     } else {
         if (!is_a($ldap, 'Net_LDAP')) {
             $ldap = false;
             // throw error
         } else {
             // store the provided ldap object internally, if we haven't got one already
             if (!$this->_ldap) {
                 $this->_ldap =& $ldap;
             }
         }
     }
     // ensure we have a valid LDAP object
     if (!is_a($ldap, 'Net_LDAP')) {
         return PEAR::raiseError("Need a Net_LDAP object as parameter");
     }
     $link = $ldap->getLink();
     /*
      * Delete the entry
      */
     if (true === $this->_delete) {
         return $ldap->delete($this);
     }
     /*
      * New entry
      */
     if (true === $this->_new) {
         $msg = $ldap->add($this);
         if (Net_LDAP::isError($msg)) {
             return $msg;
         }
         $this->_new = false;
         $this->_changes['add'] = array();
         $this->_changes['delete'] = array();
         $this->_changes['replace'] = array();
         $this->_original = $this->_attributes;
         $return = true;
         return $return;
     }
     /*
      * Rename/move entry
      */
     if (false == is_null($this->_newdn)) {
         if ($ldap->getLDAPVersion() !== 3) {
             return PEAR::raiseError("Renaming/Moving an entry is only supported in LDAPv3");
         }
         // make dn relative to parent (needed for ldap rename)
         $parent = Net_LDAP_Util::ldap_explode_dn($this->_newdn, array('casefolding' => 'none', 'reverse' => false, 'onlyvalues' => false));
         if (Net_LDAP::isError($parent)) {
             return $parent;
         }
         $child = array_shift($parent);
         // maybe the dn consist of a multivalued RDN, we must build the dn in this case
         // because the $child-RDN is an array!
         if (is_array($child)) {
             $child = Net_LDAP_Util::canonical_dn($child);
         }
         $parent = Net_LDAP_Util::canonical_dn($parent);
         // rename
         if (false == @ldap_rename($link, $this->_dn, $child, $parent, true)) {
             return PEAR::raiseError("Entry not renamed: " . @ldap_error($link), @ldap_errno($link));
         }
         // reflect changes to local copy
         $this->_dn = $this->_newdn;
         $this->_newdn = null;
     }
     /*
      * Carry out modifications to the entry
      */
     // ADD
     foreach ($this->_changes["add"] as $attr => $value) {
         // if attribute exists, add new values
         if ($this->exists($attr)) {
             if (false === @ldap_mod_add($link, $this->dn(), array($attr => $value))) {
                 return PEAR::raiseError("Could not add new values to attribute {$attr}: " . @ldap_error($link), @ldap_errno($link));
             }
         } else {
             // new attribute
             if (false === @ldap_modify($link, $this->dn(), array($attr => $value))) {
                 return PEAR::raiseError("Could not add new attribute {$attr}: " . @ldap_error($link), @ldap_errno($link));
             }
         }
         // all went well here, I guess
         unset($this->_changes["add"][$attr]);
     }
     // DELETE
     foreach ($this->_changes["delete"] as $attr => $value) {
         // In LDAPv3 you need to specify the old values for deleting
         if (is_null($value) && $ldap->getLDAPVersion() === 3) {
             $value = $this->_original[$attr];
         }
         if (false === @ldap_mod_del($link, $this->dn(), array($attr => $value))) {
             return PEAR::raiseError("Could not delete attribute {$attr}: " . @ldap_error($link), @ldap_errno($link));
         }
         unset($this->_changes["delete"][$attr]);
     }
     // REPLACE
     foreach ($this->_changes["replace"] as $attr => $value) {
         if (false === @ldap_modify($link, $this->dn(), array($attr => $value))) {
             return PEAR::raiseError("Could not replace attribute {$attr} values: " . @ldap_error($link), @ldap_errno($link));
         }
         unset($this->_changes["replace"][$attr]);
     }
     // all went well, so _original (server) becomes _attributes (local copy)
     $this->_original = $this->_attributes;
     $return = true;
     return $return;
 }
Exemple #4
0
 /**
  * Tell if a dn already exists
  *
  * @param string $dn  The DN of the object to test
  * @return boolean
  */
 function dnExists($dn)
 {
     // make dn relative to parent
     $base = Net_LDAP_Util::ldap_explode_dn($this->_newdn, array('casefolding' => 'none', 'reverse' => false, 'onlyvalues' => false));
     if (Net_LDAP::isError($base)) {
         return $base;
     }
     $filter = array_shift($base);
     // maybe the dn consist of a multivalued RDN, we must build the dn in this case
     // because the $child-RDN is an array!
     if (is_array($filter)) {
         $filter = Net_LDAP_Util::canonical_dn($filter);
     }
     $base = Net_LDAP_Util::canonical_dn($base);
     $result = @ldap_list($this->_link, $base, $filter, array(), 1, 1);
     if (ldap_errno($this->_link) == 32) {
         $return = false;
         return $return;
     }
     if (ldap_errno($this->_link) != 0) {
         PEAR::raiseError(ldap_error($this->_link), ldap_errno($this->_link));
     }
     if (@ldap_count_entries($this->_link, $result)) {
         $return = true;
         return $return;
     }
     $return = false;
     return $return;
 }