Автор: Chad Sikorra (Chad.Sikorra@gmail.com)
Пример #1
0
 /**
  * {@inheritdoc}
  */
 public function toLdap($password)
 {
     $this->validateConfiguration();
     if (!is_null($this->getLdapConnection())) {
         $password = LdapUtilities::encode($password, $this->getLdapConnection()->getConfig()->getEncoding());
     }
     return iconv("UTF-8", "UTF-16LE", '"' . $password . '"');
 }
Пример #2
0
 /**
  * {@inheritdoc}
  */
 public function getUsername($username)
 {
     if (LdapUtilities::isValidGuid($username)) {
         $username = '******' . $username . '}';
     } elseif (!(LdapUtilities::isValidSid($username) || $this->isValidUserDn($username) || $this->isInUpnForm($username))) {
         $username = parent::getUsername($username);
     }
     return $username;
 }
Пример #3
0
 /**
  * @param string $sid The SID in string, short name, or binary form.
  */
 public function __construct($sid)
 {
     if (LdapUtilities::isValidSid($sid)) {
         $this->decodeFromString($sid);
     } elseif (array_key_exists(strtoupper($sid), self::SHORT_NAME)) {
         $this->decodeFromString(self::SHORT_NAME[strtoupper($sid)]);
     } else {
         $this->decodeFromBinary($sid);
     }
 }
Пример #4
0
 /**
  * @param array $attributes
  * @param null|string $alias
  * @return array
  */
 protected function getAttributesForAlias(array $attributes, $alias)
 {
     $toSelect = [];
     foreach ($attributes as $attribute) {
         list($attrAlias, $attrSelect) = LdapUtilities::getAliasAndAttribute($attribute);
         if (!$attrAlias || $attrAlias == $alias) {
             $toSelect[] = $attrSelect;
         }
     }
     return $toSelect;
 }
Пример #5
0
 /**
  * {@inheritdoc}
  */
 public function toLdap($sid)
 {
     if (!LdapUtilities::isValidSid($sid)) {
         throw new AttributeConverterException(sprintf('Expected a string SID but got "%s".', $sid));
     }
     $sid = (new SID($sid))->toBinary();
     if ($this->getOperationType() == self::TYPE_SEARCH_TO) {
         // All hex parts must have a leading backslash for the search.
         $sid = '\\' . implode('\\', str_split(bin2hex($sid), '2'));
     }
     return $sid;
 }
Пример #6
0
 /**
  * {@inheritdoc}
  */
 public function toLdap($guid)
 {
     $guid = strtolower($guid) === self::AUTO ? LdapUtilities::uuid4() : $guid;
     if (!LdapUtilities::isValidGuid($guid)) {
         throw new AttributeConverterException(sprintf('The value "%s" is not a valid GUID.', $guid));
     }
     $guid = (new GUID($guid))->toBinary();
     if ($this->getOperationType() == self::TYPE_SEARCH_TO) {
         $guid = implode('', preg_filter('/^/', '\\', str_split(bin2hex($guid), 2)));
     }
     return $guid;
 }
Пример #7
0
 /**
  * @param string $guid
  */
 protected function decodeFromBinary($guid)
 {
     $hex = unpack('H*hex', $guid)['hex'];
     $guidStrings = [];
     foreach ($this->guidSections as $section) {
         $guidStrings[] = $this->parseSection($hex, $section);
     }
     $guid = implode('-', $guidStrings);
     if (!LdapUtilities::isValidGuid($guid)) {
         throw new \UnexpectedValueException(sprintf('The GUID with value "%s" is not valid.', $guid));
     }
     $this->guid = $guid;
 }
Пример #8
0
 /**
  * {@inheritdoc}
  */
 public function toLdapFilter($alias = null)
 {
     if ($this->skipFilterForAlias($alias)) {
         return '';
     }
     if (!LdapUtilities::isValidAttributeFormat($this->oid)) {
         throw new LdapQueryException(sprintf('Matching rule "%s" is not a valid format.', $this->oid));
     }
     if ($this->getValueForQuery($alias) instanceof BaseOperator) {
         return $this->getValueForQuery($alias)->toLdapFilter($alias);
     }
     return self::SEPARATOR_START . $this->getAttributeToQuery($alias) . ':' . $this->oid . ':' . $this->operatorSymbol . LdapUtilities::escapeValue($this->getValueForQuery($alias), null, LDAP_ESCAPE_FILTER) . self::SEPARATOR_END;
 }
Пример #9
0
 /**
  * Determine how to get the value for the attribute from the LDAP entry being compared, and return that value.
  *
  * @param array|LdapObject $entry
  * @param string $attribute
  * @return mixed
  */
 protected function getComparisonValue($entry, $attribute)
 {
     $alias = null;
     if (!empty($this->aliases)) {
         list($alias, $attribute) = LdapUtilities::getAliasAndAttribute($attribute);
     }
     $value = '';
     if (is_array($entry) && isset($entry[$attribute])) {
         $value = $entry[$attribute];
         // Be forgiving if they are hydrating to an array and the case of the attribute was not correct.
     } elseif (is_array($entry) && array_key_exists(MBString::strtolower($attribute), MBString::array_change_key_case($entry))) {
         $value = MBString::array_change_key_case($entry)[MBString::strtolower($attribute)];
         // Only get the value if there is no alias requested, or if an alias was requested the object type must match the alias.
     } elseif ($entry instanceof LdapObject && (!$alias || $entry->isType($this->aliases[$alias]->getObjectType())) && $entry->has($attribute)) {
         $value = $entry->get($attribute);
     }
     // How to handle multi-valued attributes? This will at least prevent errors, but may not be accurate.
     $value = is_array($value) ? reset($value) : $value;
     return $this->convertValueToString($value);
 }
Пример #10
0
 /**
  * This formats the orderBy array to ignore case differences between the orderBy name and the actually selected name,
  * such as for sorting arrays.
  * 
  * @param $selected
  * @param $aliases
  * @return array
  */
 protected function getFormattedOrderBy($selected, $aliases)
 {
     if (!empty($aliases) && !$this->isWildCardSelection()) {
         $orderBy = [];
         foreach ($this->orderBy as $attribute => $direction) {
             list($alias, $attr) = LdapUtilities::getAliasAndAttribute($attribute);
             $orderAttr = MBString::array_search_get_value($attr, $selected);
             $orderAttr = $alias ? "{$alias}.{$orderAttr}" : $orderAttr;
             $orderBy[$orderAttr] = $direction;
         }
     } else {
         $orderBy = $this->orderBy;
     }
     return $orderBy;
 }
 /**
  * Check all of the groups that are valid for a specific role against all of the LDAP groups that the user belongs
  * to.
  * 
  * @param array $roleGroups
  * @param LdapObjectCollection $ldapGroups
  * @return bool
  */
 protected function hasGroupForRoles(array $roleGroups, LdapObjectCollection $ldapGroups)
 {
     foreach ($roleGroups as $roleGroup) {
         if (LdapUtilities::isValidLdapObjectDn($roleGroup)) {
             $attribute = 'dn';
         } elseif (preg_match(LdapUtilities::MATCH_GUID, $roleGroup)) {
             $attribute = $this->roleAttrMap['guid'];
         } elseif (preg_match(LdapUtilities::MATCH_SID, $roleGroup)) {
             $attribute = $this->roleAttrMap['sid'];
         } else {
             $attribute = $this->roleAttrMap['name'];
         }
         if ($this->hasGroupWithAttributeValue($ldapGroups, $attribute, $roleGroup)) {
             return true;
         }
     }
     return false;
 }
Пример #12
0
 /**
  * Builds the DN based off of the "name" attribute. The name attribute should be mapped to the "cn" attribute in
  * pretty much all cases except for creating an OU object. Then the "name" attribute should be mapped to "ou".
  *
  * @param AddOperation $operation
  */
 protected function setDnToUse(AddOperation $operation)
 {
     // If the DN was explicitly set, don't do anything.
     if ($operation->getDn()) {
         return;
     }
     if (!$this->schema) {
         throw new LogicException("You must explicitly set the DN or specify a schema type.");
     }
     if (!$this->schema->hasAttribute('name')) {
         throw new LogicException('To create an object you must specify the name attribute in the schema. That attribute should typically' . ' map to the "cn" attribute, as it will use that as the base of the distinguished name.');
     }
     $location = $operation->getLocation() ?: $this->schema->getDefaultContainer();
     if (empty($location)) {
         throw new LogicException('You must specify a container or OU to place this LDAP object in.');
     }
     $attribute = $this->schema->getAttributeToLdap('name');
     $rdnValue = LdapUtilities::escapeValue($operation->getAttributes()[$attribute], null, LDAP_ESCAPE_DN);
     $location = $this->resolveParameters(['container' => $location])['container'];
     $operation->setDn($attribute . '=' . $rdnValue . ',' . $location);
 }
Пример #13
0
 /**
  * {@inheritdoc}
  */
 public function getLogArray()
 {
     return $this->mergeLogDefaults(['DN' => $this->properties['dn'], 'Batch' => print_r(LdapUtilities::sanitizeBatchArray($this->getBatchArray()), true)]);
 }
Пример #14
0
 /**
  * Encodes any values with the needed type for LDAP.
  *
  * @param array|string $values
  * @return array
  */
 protected function encodeValues($values)
 {
     if (is_null($this->connection) || $this->type == AttributeConverterInterface::TYPE_SEARCH_FROM) {
         return $values;
     }
     $encoded = is_array($values) ? $values : [$values];
     foreach ($encoded as $index => $value) {
         if (is_string($value)) {
             $encoded[$index] = LdapUtilities::encode($value, $this->connection->getConfig()->getEncoding());
         }
     }
     // This is to pass it back the same way it was received. ldap_modify_batch is picky about values being an array.
     return is_array($values) ? $encoded : reset($encoded);
 }
Пример #15
0
 /**
  * {@inheritdoc}
  */
 public function toLdapFilter($alias = null)
 {
     if ($this->skipFilterForAlias($alias)) {
         return '';
     }
     if ($this->getValueForQuery($alias) instanceof BaseOperator) {
         return $this->getValueForQuery($alias)->toLdapFilter($alias);
     }
     if ($this->wildcardType == self::CONTAINS) {
         $value = '*' . LdapUtilities::escapeValue($this->getValueForQuery($alias), null, LDAP_ESCAPE_FILTER) . '*';
     } elseif ($this->wildcardType == self::STARTS_WITH) {
         $value = LdapUtilities::escapeValue($this->getValueForQuery($alias), null, LDAP_ESCAPE_FILTER) . '*';
     } elseif ($this->wildcardType == self::ENDS_WITH) {
         $value = '*' . LdapUtilities::escapeValue($this->getValueForQuery($alias), null, LDAP_ESCAPE_FILTER);
     } elseif ($this->wildcardType == self::LIKE) {
         $value = LdapUtilities::escapeValue($this->getValueForQuery($alias), '*', LDAP_ESCAPE_FILTER);
     } else {
         $value = '*';
     }
     return self::SEPARATOR_START . $this->getAttributeToQuery($alias) . $this->operatorSymbol . $value . self::SEPARATOR_END;
 }
Пример #16
0
 /**
  * {@inheritdoc}
  */
 public function toOperation()
 {
     // If this is a move operation to a new OU and we have a DN already, then we can figure out the RDN.
     if (is_null($this->newRdn) && !is_null($this->newSuperior)) {
         $rdn = LdapUtilities::getRdnFromDn($this->dn);
     } else {
         $rdn = $this->newRdn;
     }
     return new RenameOperation($this->dn, $rdn, $this->newSuperior, $this->deleteOldRdn);
 }
Пример #17
0
 /**
  * @param LdapQueryBuilder $query
  * @param string $value
  * @return bOr
  */
 protected function getQueryOrStatement(LdapQueryBuilder $query, $value)
 {
     $bOr = $query->filter()->bOr();
     $opType = AttributeConverterInterface::TYPE_SEARCH_TO;
     if (LdapUtilities::isValidGuid($value)) {
         $bOr->add($query->filter()->eq('objectGuid', (new ConvertWindowsGuid())->setOperationType($opType)->toLdap($value)));
     } elseif (LdapUtilities::isValidSid($value)) {
         $bOr->add($query->filter()->eq('objectSid', (new ConvertWindowsSid())->setOperationType($opType)->toLdap($value)));
     }
     return $bOr;
 }
Пример #18
0
 function it_should_check_if_a_value_is_a_valid_GUID()
 {
     $this::isValidGuid(LdapUtilities::uuid4())->shouldBeEqualTo(true);
     $this::isValidGuid('bc7d93d1-3d4d-4535-88bb-d61758684700')->shouldBeEqualTo(true);
     $this::isValidGuid('bc7d93d1-3d4d-4535-88bb')->shouldBeEqualTo(false);
     $this::isValidGuid('bc7d93d-3d4-4535-88bb-d6175868470')->shouldBeEqualTo(false);
     $this::isValidGuid('foo')->shouldBeEqualTo(false);
 }
Пример #19
0
 /**
  * This will get the translated attribute or just the attribute if no schema translation was done.
  *
  * @param null|string $alias
  * @return string
  * @throws LdapQueryException
  */
 protected function getAttributeToQuery($alias)
 {
     $attribute = $this->getTranslatedAttribute($alias) ?: $this->getAttribute();
     // This avoids possible LDAP injection from unverified input for an attribute name.
     if (!LdapUtilities::isValidAttributeFormat($attribute)) {
         throw new LdapQueryException(sprintf('Attribute "%s" is not a valid name or OID.', $attribute));
     }
     return $attribute;
 }
Пример #20
0
 /**
  * Binds to LDAP with the supplied credentials or anonymously if specified.
  *
  * @param string $username The username to bind with.
  * @param string $password The password to bind with.
  * @param bool $anonymous Whether this is an anonymous bind attempt.
  * @throws LdapBindException
  */
 protected function bind($username, $password, $anonymous = false)
 {
     if ($anonymous) {
         $this->isBound = @ldap_bind($this->connection);
     } else {
         $this->isBound = @ldap_bind($this->connection, LdapUtilities::encode($username, $this->config->getEncoding()), LdapUtilities::encode($password, $this->config->getEncoding()));
     }
     if (!$this->isBound) {
         throw new LdapBindException(sprintf('Unable to bind to LDAP: %s', $this->getLastError()), $this->getExtendedErrorNumber());
     }
 }
Пример #21
0
 /**
  * @param string $sid
  * @param string $type
  * @return SID
  * @throws SddlParserException
  */
 protected function getSid($sid, $type)
 {
     $sid = strtoupper($sid);
     // This is a SID short name, or explicit SID, that requires no domain SID lookup...
     if (array_key_exists($sid, SID::SHORT_NAME) || LdapUtilities::isValidSid($sid)) {
         $sid = new SID($sid);
         // This is a SID that requires a domain SID or root domain SID lookup...
     } elseif (array_key_exists($sid, SID::SHORT_NAME_DOMAIN) || array_key_exists($sid, SID::SHORT_NAME_ROOT_DOMAIN)) {
         $sid = $this->getWellKnownDomainSid($sid, array_key_exists($sid, SID::SHORT_NAME_ROOT_DOMAIN));
     } else {
         throw new SddlParserException(sprintf('The value "%s" is not a valid SID for the %s.', $sid, $type));
     }
     return $sid;
 }
Пример #22
0
 /**
  * Moves an object from one container/OU to another in LDAP.
  *
  * @param LdapObject $ldapObject
  * @param string $container
  */
 public function move(LdapObject $ldapObject, $container)
 {
     $event = new LdapObjectMoveEvent(Event::LDAP_OBJECT_BEFORE_MOVE, $ldapObject, $container);
     $this->dispatcher->dispatch($event);
     $container = $event->getContainer();
     $this->validateObject($ldapObject);
     $operation = new RenameOperation($ldapObject->get('dn'), LdapUtilities::getRdnFromDn($ldapObject->get('dn')), $container, true);
     $this->connection->execute($operation);
     // Update the object to reference the new DN after the move...
     $newDn = LdapUtilities::getRdnFromDn($ldapObject->get('dn')) . ',' . $container;
     $ldapObject->refresh(['dn' => $newDn]);
     $ldapObject->getBatchCollection()->setDn($newDn);
     $this->dispatcher->dispatch(new LdapObjectMoveEvent(Event::LDAP_OBJECT_AFTER_MOVE, $ldapObject, $container));
 }
Пример #23
0
 /**
  * {@inheritdoc}
  */
 public function getLogArray()
 {
     return $this->mergeLogDefaults(['DN' => $this->properties['dn'], 'Attributes' => print_r(LdapUtilities::sanitizeAttributeArray($this->properties['attributes']), true)]);
 }