/** * Constructor. * * @param string $field * @param string $operator * @param string $value * * @throws InvalidQueryOperatorException */ public function __construct($field, $operator, $value) { // We'll escape the field to avoid allowing unsafe characters inside. $this->field = Utilities::escape($field, null, 3); // Validate and retrieve the operator. $this->operator = $this->validateOperator($operator); // Completely escape the value. $this->value = Utilities::escape($value); }
/** * Returns the group's member names only. * * @return array */ public function getMemberNames() { $members = []; $dns = $this->getAttribute($this->schema->member()) ?: []; foreach ($dns as $dn) { $exploded = Utilities::explodeDn($dn); if (array_key_exists(0, $exploded)) { $members[] = $exploded[0]; } } return $members; }
/** * Coping with AD not returning the primary group. * * http://support.microsoft.com/?kbid=321360. * * @param string $group The name of the group * @param string $user The username of the user * * @return bool */ public function getPrimaryGroup($group, $user) { $group = $this->find($group); $user = $this->getManager()->users()->find($user); if ($group instanceof Group && $user instanceof User) { $sid = Utilities::binarySidToText($group->getSid()); $result = $this->getManager()->search()->where(ActiveDirectory::OBJECT_SID, '=', $sid)->first(); if ($result instanceof Entry) { return $result->getDn(); } } return false; }
/** * Returns the model's SID. * * @return string */ public function getSid() { return Utilities::binarySidToString($this->getFirstAttribute($this->schema->objectSid())); }
/** * Validates if the specified group is the given parent instance. * * @param Group|string $group * @param Group $parent * * @return bool */ protected function validateGroup($group, Group $parent) { if ($group instanceof Group) { // We've been given a group instance, we'll compare their DNs. return $parent->getDn() === $group->getDn(); } if (Utilities::explodeDn($group)) { // We've been given a DN, we'll compare it to the parents. return $parent->getDn() === $group; } if (!empty($group)) { // We've been given just a string, we'll // compare it to the parents name. return $parent->getCommonName() === $group; } return false; }
/** * Assembles an RDN with the specified attribute and value. * * @param string $attribute * @param array $values * * @return null|string */ protected function assembleRdns($attribute, array $values = []) { if (count($values) > 0) { $values = array_reverse($values); $values = array_map(function ($value) use($attribute) { return sprintf('%s=%s', $attribute, Utilities::escape($value, '', 2)); }, $values); return implode(',', $values); } return; }
/** * Returns the models memberOf names only. * * @return array */ public function getMemberOfNames() { $names = []; $dns = $this->getAttribute(ActiveDirectory::MEMBER_OF); if (is_array($dns)) { foreach ($dns as $dn) { $exploded = Utilities::explodeDn($dn); if (array_key_exists(0, $exploded)) { $names[] = $exploded[0]; } } } return $names; }
/** * Returns the unescaped query. * * @return string */ public function getUnescapedQuery() { return Utilities::unescape($this->getQuery()); }
/** * Change the password of the current user. This must be performed over SSL. * * @param string $oldPassword The new password * @param string $newPassword The old password * * @throws AdldapException * @throws PasswordPolicyException * @throws WrongPasswordException * * @return bool */ public function changePassword($oldPassword, $newPassword) { $connection = $this->query->getConnection(); if (!$connection->isUsingSSL() && !$connection->isUsingTLS()) { $message = 'SSL or TLS must be configured on your web server and enabled to change passwords.'; throw new AdldapException($message); } $attribute = $this->schema->unicodePassword(); // Create batch modification for removing the old password. $remove = new BatchModification(); $remove->setAttribute($attribute); $remove->setType(LDAP_MODIFY_BATCH_REMOVE); $remove->setValues([Utilities::encodePassword($oldPassword)]); // Create batch modification for adding the new password. $add = new BatchModification(); $add->setAttribute($attribute); $add->setType(LDAP_MODIFY_BATCH_ADD); $add->setValues([Utilities::encodePassword($newPassword)]); // Add the modifications. $this->addModification($remove); $this->addModification($add); // Update the user. $result = $this->update(); if ($result === false) { // If the user failed to update, we'll see if we can // figure out why by retrieving the extended error. $error = $connection->getExtendedError(); if ($error) { $errorCode = $connection->getExtendedErrorCode(); $message = "Error: {$error}"; if ($errorCode == '0000052D') { $message = "Error: {$errorCode}. Your new password might not match the password policy."; throw new PasswordPolicyException($message); } elseif ($errorCode == '00000056') { $message = "Error: {$errorCode}. Your old password might be wrong."; throw new WrongPasswordException($message); } throw new AdldapException($message); } else { return false; } } return $result; }
/** * Adds a binding to the query. * * @param string $field * @param string $operator * @param string $value * @param string $type * * @throws InvalidQueryOperatorException * * @return Builder */ public function addBinding($field, $operator, $value, $type = 'where') { if (!array_key_exists($type, $this->bindings)) { throw new InvalidArgumentException("Invalid binding type: {$type}."); } $operator = $this->getOperator($operator); $value = Utilities::escape($value); $this->{$this->bindings[$type]}[] = compact('field', 'operator', 'value'); return $this; }
/** * Returns a new LDAP Entry instance. * * @param array $attributes * * @return Entry */ public function newLdapEntry(array $attributes = []) { $attribute = $this->schema->objectCategory(); if (array_key_exists($attribute, $attributes) && array_key_exists(0, $attributes[$attribute])) { // We'll explode the DN so we can grab it's object category. $category = Utilities::explodeDn($attributes[$attribute][0]); // Make sure the category string exists in the attribute array. if (array_key_exists(0, $category)) { $category = strtolower($category[0]); $mappings = $this->map(); // Retrieve the category model mapping. if (array_key_exists($category, $mappings)) { $model = $mappings[$category]; return $this->newModel([], $model)->setRawAttributes($attributes); } } } // A default entry model if the object category isn't found. return $this->newModel()->setRawAttributes($attributes); }
/** * Return the expiration date of the user account. * * @return DateTime|null */ public function expirationDate() { $accountExpiry = $this->getAccountExpiry(); if ($accountExpiry == 0 || $accountExpiry == $this->getSchema()->neverExpiresDate()) { return; } $unixTime = Utilities::convertWindowsTimeToUnixTime($accountExpiry); return new DateTime(date($this->dateFormat, $unixTime)); }
/** * Returns the model's object category DN in an exploded array. * * @return array */ public function getObjectCategoryArray() { return Utilities::explodeDn($this->getObjectCategoryDn()); }
/** * Change the password of the current user. This must be performed over SSL. * * @param string $oldPassword The new password * @param string $newPassword The old password * * @throws AdldapException * @throws PasswordPolicyException * @throws WrongPasswordException * * @return bool */ public function changePassword($oldPassword, $newPassword) { $connection = $this->query->getConnection(); if (!$connection->isUsingSSL() && !$connection->isUsingTLS()) { $message = 'SSL or TLS must be configured on your web server and enabled to change passwords.'; throw new AdldapException($message); } $attribute = ActiveDirectory::UNICODE_PASSWORD; $remove = new BatchModification(); $remove->setAttribute($attribute); $remove->setType(LDAP_MODIFY_BATCH_REMOVE); $remove->setValues([Utilities::encodePassword($oldPassword)]); $add = new BatchModification(); $add->setAttribute($attribute); $add->setType(LDAP_MODIFY_BATCH_ADD); $add->setValues([Utilities::encodePassword($newPassword)]); $this->addModification($remove); $this->addModification($add); $result = $this->update(); if ($result === false) { $error = $connection->getExtendedError(); if ($error) { $errorCode = $connection->getExtendedErrorCode(); $message = 'Error: ' . $error; if ($errorCode == '0000052D') { $message = "Error: {$errorCode}. Your new password might not match the password policy."; throw new PasswordPolicyException($message); } elseif ($errorCode == '00000056') { $message = "Error: {$errorCode}. Your old password might be wrong."; throw new WrongPasswordException($message); } throw new AdldapException($message); } else { return false; } } return $result; }
/** * Returns the models memberOf names only. * * @return array */ public function getMemberOfNames() { $names = []; $dns = $this->getAttribute($this->getSchema()->memberOf()); if (is_array($dns)) { foreach ($dns as $dn) { $exploded = Utilities::explodeDn($dn); if (array_key_exists(0, $exploded)) { $names[] = $exploded[0]; } } } return $names; }
/** * Assembles an RDN with the specified attribute and value. * * @param string $attribute * @param array $values * * @return string */ protected function assembleRdns($attribute, array $values = []) { return implode(',', array_map(function ($value) use($attribute) { return sprintf('%s=%s', $attribute, Utilities::escape($value, '', 2)); }, $values)); }