| 
									
										
										
										
											2011-06-26 10:44:28 +00:00
										 |  |  | <?php | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Classes and functions for importing data to LDAP | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * These classes provide differnet import formats. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @author The phpLDAPadmin development team | 
					
						
							|  |  |  |  * @package phpLDAPadmin | 
					
						
							|  |  |  |  * @see import.php and import_form.php | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Importer Class | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This class serves as a top level importer class, which will return | 
					
						
							|  |  |  |  * the correct Import class. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @package phpLDAPadmin | 
					
						
							|  |  |  |  * @subpackage Import | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | class Importer { | 
					
						
							|  |  |  | 	# Server ID that the export is linked to
 | 
					
						
							|  |  |  | 	private $server_id; | 
					
						
							|  |  |  | 	# Import Type
 | 
					
						
							|  |  |  | 	private $template_id; | 
					
						
							|  |  |  | 	private $template; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	public function __construct($server_id,$template_id) { | 
					
						
							|  |  |  | 		$this->server_id = $server_id; | 
					
						
							|  |  |  | 		$this->template_id = $template_id; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		$this->accept(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	static function types() { | 
					
						
							|  |  |  | 		$type = array(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		$details = ImportLDIF::getType(); | 
					
						
							|  |  |  | 		$type[$details['type']] = $details; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return $type; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	private function accept() { | 
					
						
							|  |  |  | 		switch($this->template_id) { | 
					
						
							|  |  |  | 			case 'LDIF': | 
					
						
							|  |  |  | 				$this->template = new ImportLDIF($this->server_id); | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			default: | 
					
						
							|  |  |  | 				die(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		$this->template->accept(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	public function getTemplate() { | 
					
						
							|  |  |  | 		return $this->template; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Import Class | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This abstract classes provides all the common methods and variables for the | 
					
						
							|  |  |  |  * custom import classes. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @package phpLDAPadmin | 
					
						
							|  |  |  |  * @subpackage Import | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | abstract class Import { | 
					
						
							|  |  |  | 	protected $server_id = null; | 
					
						
							|  |  |  | 	protected $input = null; | 
					
						
							|  |  |  | 	protected $source = array(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	public function __construct($server_id) { | 
					
						
							|  |  |  | 		$this->server_id = $server_id; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	public function accept() { | 
					
						
							|  |  |  | 		if (get_request('ldif','REQUEST')) { | 
					
						
							|  |  |  | 			$this->input = explode("\n",get_request('ldif','REQUEST')); | 
					
						
							|  |  |  | 			$this->source['name'] = 'STDIN'; | 
					
						
							|  |  |  | 			$this->source['size'] = strlen(get_request('ldif','REQUEST')); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} elseif (isset($_FILES['ldif_file']) && is_array($_FILES['ldif_file']) && ! $_FILES['ldif_file']['error']) { | 
					
						
							|  |  |  | 			$input = file_get_contents($_FILES['ldif_file']['tmp_name']); | 
					
						
							|  |  |  | 			$this->input = preg_split("/\n|\r\n|\r/",$input); | 
					
						
							|  |  |  | 			$this->source['name'] = $_FILES['ldif_file']['name']; | 
					
						
							|  |  |  | 			$this->source['size'] = $_FILES['ldif_file']['size']; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			system_message(array( | 
					
						
							|  |  |  | 				'title'=>_('No import input'), | 
					
						
							|  |  |  | 				'body'=>_('You must either upload a file or provide an import in the text box.'), | 
					
						
							|  |  |  | 				'type'=>'error'),sprintf('cmd.php?cmd=import_form&server_id=%s',get_request('server_id','REQUEST'))); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			die(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	public function getSource($attr) { | 
					
						
							|  |  |  | 		if (isset($this->source[$attr])) | 
					
						
							|  |  |  | 			return $this->source[$attr]; | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			return null; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	# @todo integrate hooks
 | 
					
						
							|  |  |  | 	public function LDAPimport() { | 
					
						
							|  |  |  | 		$template = $this->getTemplate(); | 
					
						
							|  |  |  | 		$server = $this->getServer(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		switch ($template->getType()) { | 
					
						
							|  |  |  | 			case 'add':  | 
					
						
							|  |  |  | 				return $server->add($template->getDN(),$template->getLDAPadd()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			case 'modify': | 
					
						
							|  |  |  | 				return $server->modify($template->getDN(),$template->getLDAPmodify()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			case 'moddn': | 
					
						
							|  |  |  | 			case 'modrdn': | 
					
						
							|  |  |  | 				return $server->rename($template->getDN(),$template->modrdn['newrdn'],$template->modrdn['newsuperior'],$template->modrdn['deleteoldrdn']); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			default: | 
					
						
							|  |  |  | 				debug_dump_backtrace(sprintf('Unknown template type %s',$template->getType()),1); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return true; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Import entries from LDIF | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The LDIF spec is described by RFC2849 | 
					
						
							|  |  |  |  * http://www.ietf.org/rfc/rfc2849.txt | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @package phpLDAPadmin | 
					
						
							|  |  |  |  * @subpackage Import | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | class ImportLDIF extends Import { | 
					
						
							|  |  |  | 	private $_currentLineNumber = 0; | 
					
						
							|  |  |  | 	private $_currentLine = ''; | 
					
						
							|  |  |  | 	private $template; | 
					
						
							|  |  |  | 	public $error = array(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	static public function getType() { | 
					
						
							| 
									
										
										
										
											2011-07-13 18:30:14 +00:00
										 |  |  | 		return array('type'=>'LDIF','description' => _('LDIF import'),'extension'=>'ldif'); | 
					
						
							| 
									
										
										
										
											2011-06-26 10:44:28 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	protected function getTemplate() { | 
					
						
							|  |  |  | 		return $this->template; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	protected function getServer() { | 
					
						
							|  |  |  | 		return $_SESSION[APPCONFIG]->getServer($this->server_id); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	public function readEntry() { | 
					
						
							|  |  |  | 		static $haveVersion = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if ($lines = $this->nextLines()) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			# If we have a version line.
 | 
					
						
							|  |  |  | 			if (! $haveVersion && preg_match('/^version:/',$lines[0])) { | 
					
						
							|  |  |  | 				list($text,$version) = $this->getAttrValue(array_shift($lines)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if ($version != 1) | 
					
						
							| 
									
										
										
										
											2011-09-24 22:30:00 +00:00
										 |  |  | 					return $this->error(sprintf('%s %s',_('LDIF import only supports version 1'),$version),$lines); | 
					
						
							| 
									
										
										
										
											2011-06-26 10:44:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				$haveVersion = true; | 
					
						
							|  |  |  | 				$lines = $this->nextLines(); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			$server = $this->getServer(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			# The first line should be the DN
 | 
					
						
							|  |  |  | 			if (preg_match('/^dn:/',$lines[0])) { | 
					
						
							|  |  |  | 				list($text,$dn) = $this->getAttrValue(array_shift($lines)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				# The second line should be our changetype
 | 
					
						
							|  |  |  | 				if (preg_match('/^changetype:[ ]*(delete|add|modrdn|moddn|modify)/i',$lines[0])) { | 
					
						
							|  |  |  | 					$attrvalue = $this->getAttrValue($lines[0]); | 
					
						
							|  |  |  | 					$changetype = $attrvalue[1]; | 
					
						
							|  |  |  | 					array_shift($lines); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				} else | 
					
						
							|  |  |  | 					$changetype = 'add'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				$this->template = new Template($this->server_id,null,null,$changetype); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				switch ($changetype) { | 
					
						
							|  |  |  | 					case 'add': | 
					
						
							|  |  |  | 						$rdn = get_rdn($dn); | 
					
						
							|  |  |  | 						$container = $server->getContainer($dn); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						$this->template->setContainer($container); | 
					
						
							|  |  |  | 						$this->template->accept(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						$this->getAddDetails($lines); | 
					
						
							|  |  |  | 						$this->template->setRDNAttributes($rdn); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						return $this->template; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					case 'modify': | 
					
						
							|  |  |  | 						if (! $server->dnExists($dn)) | 
					
						
							|  |  |  | 							return $this->error(sprintf('%s %s',_('DN does not exist'),$dn),$lines); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						$this->template->setDN($dn); | 
					
						
							|  |  |  | 						$this->template->accept(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						return $this->getModifyDetails($lines); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					case 'moddn': | 
					
						
							|  |  |  | 					case 'modrdn': | 
					
						
							|  |  |  | 						if (! $server->dnExists($dn)) | 
					
						
							|  |  |  | 							return $this->error(sprintf('%s %s',_('DN does not exist'),$dn),$lines); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						$this->template->setDN($dn); | 
					
						
							|  |  |  | 						$this->template->accept(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						return $this->getModRDNAttributes($lines); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					default: | 
					
						
							|  |  |  | 						if (! $server->dnExists($dn)) | 
					
						
							|  |  |  | 							return $this->error(_('Unkown change type'),$lines); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			} else | 
					
						
							|  |  |  | 				return $this->error(_('A valid dn line is required'),$lines); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} else | 
					
						
							|  |  |  | 			return false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Get the Attribute and Decoded Value | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	private function getAttrValue($line) { | 
					
						
							|  |  |  | 		list($attr,$value) = explode(':',$line,2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		# Get the DN
 | 
					
						
							|  |  |  | 		if (substr($value,0,1) == ':') | 
					
						
							|  |  |  | 			$value = base64_decode(trim(substr($value,1))); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			$value = trim($value); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return array($attr,$value); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Get the lines of the next entry | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @return The lines (unfolded) of the next entry | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	private function nextLines() { | 
					
						
							|  |  |  | 		$current = array(); | 
					
						
							|  |  |  | 		$endEntryFound = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if ($this->hasMoreEntries() && ! $this->eof()) { | 
					
						
							|  |  |  | 			# The first line is the DN one
 | 
					
						
							|  |  |  | 			$current[0]= trim($this->_currentLine); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			# While we end on a blank line, fetch the attribute lines
 | 
					
						
							|  |  |  | 			$count = 0; | 
					
						
							|  |  |  | 			while (! $this->eof() && ! $endEntryFound) { | 
					
						
							|  |  |  | 				# Fetch the next line
 | 
					
						
							|  |  |  | 				$this->nextLine(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* If the next line begin with a space, we append it to the current row | 
					
						
							|  |  |  | 				 * else we push it into the array (unwrap)*/ | 
					
						
							|  |  |  | 				if ($this->isWrappedLine()) | 
					
						
							|  |  |  | 					$current[$count] .= trim($this->_currentLine); | 
					
						
							|  |  |  | 				elseif ($this->isCommentLine()) {} | 
					
						
							|  |  |  | 				# Do nothing
 | 
					
						
							|  |  |  | 				elseif (! $this->isBlankLine()) | 
					
						
							|  |  |  | 					$current[++$count] = trim($this->_currentLine); | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					$endEntryFound = true; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			# Return the LDIF entry array
 | 
					
						
							|  |  |  | 			return $current; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} else | 
					
						
							|  |  |  | 			return array(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Private method to check if there is more entries in the input. | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @return boolean true if an entry was found, false otherwise. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	private function hasMoreEntries() { | 
					
						
							|  |  |  | 		$entry_found = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		while (! $this->eof() && ! $entry_found) { | 
					
						
							|  |  |  | 			# If it's a comment or blank line, switch to the next line
 | 
					
						
							|  |  |  | 			if ($this->isCommentLine() || $this->isBlankLine()) { | 
					
						
							|  |  |  | 				# Do nothing
 | 
					
						
							|  |  |  | 				$this->nextLine(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				$this->_currentDnLine = $this->_currentLine; | 
					
						
							|  |  |  | 				$this->dnLineNumber = $this->_currentLineNumber; | 
					
						
							|  |  |  | 				$entry_found = true; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return $entry_found; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Helper method to switch to the next line | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	private function nextLine() { | 
					
						
							|  |  |  | 		$this->_currentLineNumber++; | 
					
						
							|  |  |  | 		$this->_currentLine = array_shift($this->input); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Check if it's a comment line. | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @return boolean true if it's a comment line,false otherwise | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	private function isCommentLine() { | 
					
						
							|  |  |  | 		return substr(trim($this->_currentLine),0,1) == '#' ? true : false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Check if it's a wrapped line. | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @return boolean true if it's a wrapped line,false otherwise | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	private function isWrappedLine() { | 
					
						
							|  |  |  | 		return substr($this->_currentLine,0,1) == ' ' ? true : false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Check if is the current line is a blank line. | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @return boolean if it is a blank line,false otherwise. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	private function isBlankLine() { | 
					
						
							|  |  |  | 		return(trim($this->_currentLine) == '') ? true : false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Returns true if we reached the end of the input. | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @return boolean true if it's the end of file, false otherwise. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	public function eof() { | 
					
						
							|  |  |  | 		return count($this->input) > 0 ? false : true; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	private function error($msg,$data) { | 
					
						
							|  |  |  | 		$this->error['message'] = sprintf('%s [%s]',$msg,$this->template ? $this->template->getDN() : ''); | 
					
						
							|  |  |  | 		$this->error['line'] = $this->_currentLineNumber; | 
					
						
							|  |  |  | 		$this->error['data'] = $data; | 
					
						
							|  |  |  | 		$this->error['changetype'] = $this->template ? $this->template->getType() : 'Not set'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Method to retrieve the attribute value of a ldif line, | 
					
						
							|  |  |  | 	 * and get the base 64 decoded value if it is encoded | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	private function getAttributeValue($value) { | 
					
						
							|  |  |  | 		$return = ''; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (substr($value,0,1) == '<') { | 
					
						
							|  |  |  | 			$url = trim(substr($value,1)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (preg_match('^file://',$url)) { | 
					
						
							|  |  |  | 				$filename = substr(trim($url),7); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if ($fh = @fopen($filename,'rb')) { | 
					
						
							|  |  |  | 					if (! $return = @fread($fh,filesize($filename))) | 
					
						
							| 
									
										
										
										
											2011-07-21 17:50:57 +00:00
										 |  |  | 						return $this->error(_('Unable to read file.'),$value); | 
					
						
							| 
									
										
										
										
											2011-06-26 10:44:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					@fclose($fh); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				} else | 
					
						
							| 
									
										
										
										
											2011-07-21 17:50:57 +00:00
										 |  |  | 					return $this->error(_('Unable to read file.'),$value); | 
					
						
							| 
									
										
										
										
											2011-06-26 10:44:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			} else | 
					
						
							| 
									
										
										
										
											2011-07-21 17:50:57 +00:00
										 |  |  | 				return $this->error(_('The url attribute value should begin with file://.'),$value); | 
					
						
							| 
									
										
										
										
											2011-06-26 10:44:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		# It's a string
 | 
					
						
							|  |  |  | 		} else | 
					
						
							|  |  |  | 			$return = $value; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return trim($return); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Build the attributes array when the change type is add. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	private function getAddDetails($lines) { | 
					
						
							|  |  |  | 		foreach ($lines as $line) { | 
					
						
							|  |  |  | 			list($attr,$value) = $this->getAttrValue($line); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (is_null($attribute = $this->template->getAttribute($attr))) { | 
					
						
							|  |  |  | 				$attribute = $this->template->addAttribute($attr,array('values'=>array($value))); | 
					
						
							|  |  |  | 				$attribute->justModified(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			} else | 
					
						
							|  |  |  | 				if ($attribute->hasBeenModified()) | 
					
						
							|  |  |  | 					$attribute->addValue($value); | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					$attribute->setValue(array($value)); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Build the attributes array for the entry when the change type is modify | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	private function getModifyDetails($lines) { | 
					
						
							|  |  |  | 		if (! count($lines)) | 
					
						
							|  |  |  | 			return $this->error(_('Missing attributes for'),$lines); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		# While the array is not empty
 | 
					
						
							|  |  |  | 		while (count($lines)) { | 
					
						
							|  |  |  | 			$processline = false; | 
					
						
							|  |  |  | 			$deleteattr = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			# Get the current line with the action
 | 
					
						
							|  |  |  | 			$currentLine = array_shift($lines); | 
					
						
							|  |  |  | 			$attrvalue = $this->getAttrValue($currentLine); | 
					
						
							|  |  |  | 			$action_attribute = $attrvalue[0]; | 
					
						
							|  |  |  | 			$action_attribute_value = $attrvalue[1]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (! in_array($action_attribute,array('add','delete','replace'))) | 
					
						
							|  |  |  | 				return $this->error(_('Missing modify command add, delete or replace'),array_merge(array($currentLine),$lines)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			$processline = true; | 
					
						
							|  |  |  | 			switch ($action_attribute) { | 
					
						
							|  |  |  | 				case 'add': | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				case 'delete': | 
					
						
							|  |  |  | 					$attribute = $this->template->getAttribute($action_attribute_value); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					if (is_null($attribute)) | 
					
						
							| 
									
										
										
										
											2011-07-12 19:23:27 +00:00
										 |  |  | 						return $this->error(sprintf('%s %s',_('Attempting to delete a non existent attribute'),$action_attribute_value), | 
					
						
							| 
									
										
										
										
											2011-06-26 10:44:28 +00:00
										 |  |  | 							array_merge(array($currentLine),$lines)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					$deleteattr = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				case 'replace': | 
					
						
							|  |  |  | 					$attribute = $this->template->getAttribute($action_attribute_value); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					if (is_null($attribute)) | 
					
						
							|  |  |  | 						return $this->error(sprintf('%s %s',_('Attempting to replace a non existant attribute'),$action_attribute_value), | 
					
						
							|  |  |  | 							array_merge(array($currentLine),$lines)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				default: | 
					
						
							|  |  |  | 					debug_dump_backtrace(sprintf('Unknown action %s',$action_attribute),1); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			# Fetch the attribute for the following line
 | 
					
						
							|  |  |  | 			$currentLine = array_shift($lines); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			while ($processline && trim($currentLine) && (trim($currentLine) != '-')) { | 
					
						
							|  |  |  | 				$processline = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				# If there is a valid line
 | 
					
						
							|  |  |  | 				if (preg_match('/:/',$currentLine)) { | 
					
						
							|  |  |  | 					$attrvalue = $this->getAttrValue($currentLine); | 
					
						
							|  |  |  | 					$attr = $attrvalue[0]; | 
					
						
							|  |  |  | 					$attribute_value_part = $attrvalue[1]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					# Check that it correspond to the one specified before
 | 
					
						
							|  |  |  | 					if ($attr == $action_attribute_value) { | 
					
						
							|  |  |  | 						# Get the value part of the attribute
 | 
					
						
							|  |  |  | 						$attribute_value = $this->getAttributeValue($attribute_value_part); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						$attribute = $this->template->getAttribute($attr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						# This should be a add/replace operation
 | 
					
						
							|  |  |  | 						switch ($action_attribute) { | 
					
						
							|  |  |  | 							case 'add': | 
					
						
							|  |  |  | 								if (is_null($attribute)) | 
					
						
							|  |  |  | 									$attribute = $this->template->addAttribute($attr,array('values'=>array($attribute_value_part))); | 
					
						
							|  |  |  | 								else | 
					
						
							|  |  |  | 									$attribute->addValue($attribute_value_part,-1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 								$attribute->justModified(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 								break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 							case 'delete': | 
					
						
							|  |  |  | 								$deleteattr = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 								if ($key = array_search($attribute_value_part,$attribute->getValues())) | 
					
						
							|  |  |  | 									$attribute->delValue($key); | 
					
						
							|  |  |  | 								else | 
					
						
							| 
									
										
										
										
											2011-08-09 17:09:39 +00:00
										 |  |  | 									return $this->error(sprintf('%s %s',_('Value to delete does not exist in DN'),$attribute_value_part), | 
					
						
							| 
									
										
										
										
											2011-06-26 10:44:28 +00:00
										 |  |  | 										array_merge(array($currentLine),$lines)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 								break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 							case 'replace': | 
					
						
							|  |  |  | 								if ($attribute->hasBeenModified()) | 
					
						
							|  |  |  | 									$attribute->addValue($attribute_value_part,-1); | 
					
						
							|  |  |  | 								else | 
					
						
							|  |  |  | 									$attribute->setValue(array($attribute_value_part)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 								break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 							default: | 
					
						
							|  |  |  | 								debug_dump_backtrace(sprintf('Unexpected operation %s',$action_attribute)); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					} else | 
					
						
							| 
									
										
										
										
											2011-07-15 18:10:43 +00:00
										 |  |  | 						return $this->error(sprintf(_('The attribute to modify doesn\'t match the one specified by %s.'),$action_attribute), | 
					
						
							| 
									
										
										
										
											2011-06-26 10:44:28 +00:00
										 |  |  | 							array_merge(array($currentLine),$lines)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				} else | 
					
						
							|  |  |  | 					return $this->error(sprintf('%s %s',_('Attribute not valid'),$currentLine), | 
					
						
							|  |  |  | 						array_merge(array($currentLine),$lines)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				$currentLine = array_shift($lines); | 
					
						
							|  |  |  | 				if (trim($currentLine)) | 
					
						
							|  |  |  | 					$processline = true; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if ($action_attribute == 'delete' && $deleteattr) | 
					
						
							|  |  |  | 				$attribute->setValue(array()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return $this->template; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Build the attributes for the entry when the change type is modrdn | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	function getModRDNAttributes($lines) { | 
					
						
							|  |  |  | 		$server = $this->getServer(); | 
					
						
							|  |  |  | 		$attrs = array(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		# MODRDN MODDN should only be 2 or 3 lines.
 | 
					
						
							|  |  |  | 		if (count($lines) != 2 && count($lines) !=3) | 
					
						
							|  |  |  | 			return $this->error(_('Invalid entry'),$lines); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			$currentLine = array_shift($lines); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			# First we need to check if there is an new rdn specified
 | 
					
						
							|  |  |  | 			if (preg_match('/^newrdn:(:?)/',$currentLine)) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				$attrvalue = $this->getAttrValue($currentLine); | 
					
						
							|  |  |  | 				$attrs['newrdn'] = $attrvalue[1]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				$currentLine = array_shift($lines); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if (preg_match('/^deleteoldrdn:[ ]*(0|1)/',$currentLine)) { | 
					
						
							|  |  |  | 					$attrvalue = $this->getAttrValue($currentLine); | 
					
						
							|  |  |  | 					$attrs['deleteoldrdn'] = $attrvalue[1]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					# Switch to the possible new superior attribute
 | 
					
						
							|  |  |  | 					if (count($lines)) { | 
					
						
							|  |  |  | 						$currentLine = array_shift($lines); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						# then the possible new superior attribute
 | 
					
						
							|  |  |  | 						if (preg_match('/^newsuperior:/',$currentLine)) { | 
					
						
							|  |  |  | 							$attrvalue = $this->getAttrValue($currentLine); | 
					
						
							|  |  |  | 							$attrs['newsuperior'] = $attrvalue[1]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						} else | 
					
						
							|  |  |  | 							return $this->error(_('A valid newsuperier attribute should be specified'),$lines); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					} else | 
					
						
							|  |  |  | 						$attrs['newsuperior'] = $server->getContainer($this->template->getDN()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				} else | 
					
						
							|  |  |  | 					return $this->error(_('A valid deleteoldrdn attribute should be specified'),$lines); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			} else | 
					
						
							|  |  |  | 				return $this->error(_('A valid newrdn attribute should be specified'),$lines); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		# Well do something out of the ordinary here, since our template doesnt handle mod[r]dn yet.
 | 
					
						
							|  |  |  | 		$this->template->modrdn = $attrs; | 
					
						
							|  |  |  | 		return $this->template; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | ?>
 |