*/ private const MAP_ATTR_TO_STR_TYPE = [ self::OID_DN_QUALIFIER => Element::TYPE_PRINTABLE_STRING, self::OID_COUNTRY_NAME => Element::TYPE_PRINTABLE_STRING, self::OID_SERIAL_NUMBER => Element::TYPE_PRINTABLE_STRING, ]; /** * OID to attribute names mapping. * * First name is the primary name. If there's more than one name, others may be used as an alias. * * Generated using ldap-attribs.py. * * @internal * * @var array> */ private const MAP_OID_TO_NAME = [ '0.9.2342.19200300.100.1.1' => ['uid', 'userid'], '0.9.2342.19200300.100.1.2' => ['textEncodedORAddress'], '0.9.2342.19200300.100.1.3' => ['mail', 'rfc822Mailbox'], '0.9.2342.19200300.100.1.4' => ['info'], '0.9.2342.19200300.100.1.5' => ['drink', 'favouriteDrink'], '0.9.2342.19200300.100.1.6' => ['roomNumber'], '0.9.2342.19200300.100.1.7' => ['photo'], '0.9.2342.19200300.100.1.8' => ['userClass'], '0.9.2342.19200300.100.1.9' => ['host'], '0.9.2342.19200300.100.1.10' => ['manager'], '0.9.2342.19200300.100.1.11' => ['documentIdentifier'], '0.9.2342.19200300.100.1.12' => ['documentTitle'], '0.9.2342.19200300.100.1.13' => ['documentVersion'], '0.9.2342.19200300.100.1.14' => ['documentAuthor'], '0.9.2342.19200300.100.1.15' => ['documentLocation'], '0.9.2342.19200300.100.1.20' => ['homePhone', 'homeTelephoneNumber'], '0.9.2342.19200300.100.1.21' => ['secretary'], '0.9.2342.19200300.100.1.22' => ['otherMailbox'], '0.9.2342.19200300.100.1.25' => ['dc', 'domainComponent'], '0.9.2342.19200300.100.1.26' => ['aRecord'], '0.9.2342.19200300.100.1.27' => ['mDRecord'], '0.9.2342.19200300.100.1.28' => ['mXRecord'], '0.9.2342.19200300.100.1.29' => ['nSRecord'], '0.9.2342.19200300.100.1.30' => ['sOARecord'], '0.9.2342.19200300.100.1.31' => ['cNAMERecord'], '0.9.2342.19200300.100.1.37' => ['associatedDomain'], '0.9.2342.19200300.100.1.38' => ['associatedName'], '0.9.2342.19200300.100.1.39' => ['homePostalAddress'], '0.9.2342.19200300.100.1.40' => ['personalTitle'], '0.9.2342.19200300.100.1.41' => ['mobile', 'mobileTelephoneNumber'], '0.9.2342.19200300.100.1.42' => ['pager', 'pagerTelephoneNumber'], '0.9.2342.19200300.100.1.43' => ['co', 'friendlyCountryName'], '0.9.2342.19200300.100.1.44' => ['uniqueIdentifier'], '0.9.2342.19200300.100.1.45' => ['organizationalStatus'], '0.9.2342.19200300.100.1.46' => ['janetMailbox'], '0.9.2342.19200300.100.1.47' => ['mailPreferenceOption'], '0.9.2342.19200300.100.1.48' => ['buildingName'], '0.9.2342.19200300.100.1.49' => ['dSAQuality'], '0.9.2342.19200300.100.1.50' => ['singleLevelQuality'], '0.9.2342.19200300.100.1.51' => ['subtreeMinimumQuality'], '0.9.2342.19200300.100.1.52' => ['subtreeMaximumQuality'], '0.9.2342.19200300.100.1.53' => ['personalSignature'], '0.9.2342.19200300.100.1.54' => ['dITRedirect'], '0.9.2342.19200300.100.1.55' => ['audio'], '0.9.2342.19200300.100.1.56' => ['documentPublisher'], '0.9.2342.19200300.100.1.60' => ['jpegPhoto'], '1.2.840.113549.1.9.1' => ['email', 'emailAddress', 'pkcs9email'], '1.2.840.113556.1.2.102' => ['memberOf'], '1.3.6.1.1.1.1.0' => ['uidNumber'], '1.3.6.1.1.1.1.1' => ['gidNumber'], '1.3.6.1.1.1.1.2' => ['gecos'], '1.3.6.1.1.1.1.3' => ['homeDirectory'], '1.3.6.1.1.1.1.4' => ['loginShell'], '1.3.6.1.1.1.1.5' => ['shadowLastChange'], '1.3.6.1.1.1.1.6' => ['shadowMin'], '1.3.6.1.1.1.1.7' => ['shadowMax'], '1.3.6.1.1.1.1.8' => ['shadowWarning'], '1.3.6.1.1.1.1.9' => ['shadowInactive'], '1.3.6.1.1.1.1.10' => ['shadowExpire'], '1.3.6.1.1.1.1.11' => ['shadowFlag'], '1.3.6.1.1.1.1.12' => ['memberUid'], '1.3.6.1.1.1.1.13' => ['memberNisNetgroup'], '1.3.6.1.1.1.1.14' => ['nisNetgroupTriple'], '1.3.6.1.1.1.1.15' => ['ipServicePort'], '1.3.6.1.1.1.1.16' => ['ipServiceProtocol'], '1.3.6.1.1.1.1.17' => ['ipProtocolNumber'], '1.3.6.1.1.1.1.18' => ['oncRpcNumber'], '1.3.6.1.1.1.1.19' => ['ipHostNumber'], '1.3.6.1.1.1.1.20' => ['ipNetworkNumber'], '1.3.6.1.1.1.1.21' => ['ipNetmaskNumber'], '1.3.6.1.1.1.1.22' => ['macAddress'], '1.3.6.1.1.1.1.23' => ['bootParameter'], '1.3.6.1.1.1.1.24' => ['bootFile'], '1.3.6.1.1.1.1.26' => ['nisMapName'], '1.3.6.1.1.1.1.27' => ['nisMapEntry'], '1.3.6.1.1.4' => ['vendorName'], '1.3.6.1.1.5' => ['vendorVersion'], '1.3.6.1.1.16.4' => ['entryUUID'], '1.3.6.1.1.20' => ['entryDN'], '2.5.4.0' => ['objectClass'], '2.5.4.1' => ['aliasedObjectName', 'aliasedEntryName'], '2.5.4.2' => ['knowledgeInformation'], '2.5.4.3' => ['cn', 'commonName'], '2.5.4.4' => ['sn', 'surname'], '2.5.4.5' => ['serialNumber'], '2.5.4.6' => ['c', 'countryName'], '2.5.4.7' => ['l', 'localityName'], '2.5.4.8' => ['st', 'stateOrProvinceName'], '2.5.4.9' => ['street', 'streetAddress'], '2.5.4.10' => ['o', 'organizationName'], '2.5.4.11' => ['ou', 'organizationalUnitName'], '2.5.4.12' => ['title'], '2.5.4.13' => ['description'], '2.5.4.14' => ['searchGuide'], '2.5.4.15' => ['businessCategory'], '2.5.4.16' => ['postalAddress'], '2.5.4.17' => ['postalCode'], '2.5.4.18' => ['postOfficeBox'], '2.5.4.19' => ['physicalDeliveryOfficeName'], '2.5.4.20' => ['telephoneNumber'], '2.5.4.21' => ['telexNumber'], '2.5.4.22' => ['teletexTerminalIdentifier'], '2.5.4.23' => ['facsimileTelephoneNumber', 'fax'], '2.5.4.24' => ['x121Address'], '2.5.4.25' => ['internationaliSDNNumber'], '2.5.4.26' => ['registeredAddress'], '2.5.4.27' => ['destinationIndicator'], '2.5.4.28' => ['preferredDeliveryMethod'], '2.5.4.29' => ['presentationAddress'], '2.5.4.30' => ['supportedApplicationContext'], '2.5.4.31' => ['member'], '2.5.4.32' => ['owner'], '2.5.4.33' => ['roleOccupant'], '2.5.4.34' => ['seeAlso'], '2.5.4.35' => ['userPassword'], '2.5.4.36' => ['userCertificate'], '2.5.4.37' => ['cACertificate'], '2.5.4.38' => ['authorityRevocationList'], '2.5.4.39' => ['certificateRevocationList'], '2.5.4.40' => ['crossCertificatePair'], '2.5.4.41' => ['name'], '2.5.4.42' => ['givenName', 'gn'], '2.5.4.43' => ['initials'], '2.5.4.44' => ['generationQualifier'], '2.5.4.45' => ['x500UniqueIdentifier'], '2.5.4.46' => ['dnQualifier'], '2.5.4.47' => ['enhancedSearchGuide'], '2.5.4.48' => ['protocolInformation'], '2.5.4.49' => ['distinguishedName'], '2.5.4.50' => ['uniqueMember'], '2.5.4.51' => ['houseIdentifier'], '2.5.4.52' => ['supportedAlgorithms'], '2.5.4.53' => ['deltaRevocationList'], '2.5.4.54' => ['dmdName'], '2.5.4.65' => ['pseudonym'], '2.5.18.1' => ['createTimestamp'], '2.5.18.2' => ['modifyTimestamp'], '2.5.18.3' => ['creatorsName'], '2.5.18.4' => ['modifiersName'], '2.5.18.5' => ['administrativeRole'], '2.5.18.6' => ['subtreeSpecification'], '2.5.18.9' => ['hasSubordinates'], '2.5.18.10' => ['subschemaSubentry'], '2.5.21.1' => ['dITStructureRules'], '2.5.21.2' => ['dITContentRules'], '2.5.21.4' => ['matchingRules'], '2.5.21.5' => ['attributeTypes'], '2.5.21.6' => ['objectClasses'], '2.5.21.7' => ['nameForms'], '2.5.21.8' => ['matchingRuleUse'], '2.5.21.9' => ['structuralObjectClass'], '2.16.840.1.113730.3.1.1' => ['carLicense'], '2.16.840.1.113730.3.1.2' => ['departmentNumber'], '2.16.840.1.113730.3.1.3' => ['employeeNumber'], '2.16.840.1.113730.3.1.4' => ['employeeType'], '2.16.840.1.113730.3.1.34' => ['ref'], '2.16.840.1.113730.3.1.39' => ['preferredLanguage'], '2.16.840.1.113730.3.1.40' => ['userSMIMECertificate'], '2.16.840.1.113730.3.1.216' => ['userPKCS12'], '2.16.840.1.113730.3.1.241' => ['displayName'], ]; /** * @param string $_oid OID in dotted format */ private function __construct( protected string $_oid ) { } public static function create(string $oid): self { return new self($oid); } /** * Initialize from ASN.1. */ public static function fromASN1(ObjectIdentifier $oi): self { return self::create($oi->oid()); } /** * Initialize from attribute name. */ public static function fromName(string $name): self { $oid = self::attrNameToOID($name); return self::create($oid); } /** * Get OID of the attribute. * * @return string OID in dotted format */ public function oid(): string { return $this->_oid; } /** * Get name of the attribute. */ public function typeName(): string { if (array_key_exists($this->_oid, self::MAP_OID_TO_NAME)) { return self::MAP_OID_TO_NAME[$this->_oid][0]; } return $this->_oid; } /** * Generate ASN.1 element. */ public function toASN1(): ObjectIdentifier { return ObjectIdentifier::create($this->_oid); } /** * Convert attribute name to OID. * * @param string $name Primary attribute name or an alias * * @return string OID in dotted format */ public static function attrNameToOID(string $name): string { // if already in OID form if (preg_match('/^[0-9]+(?:\.[0-9]+)*$/', $name) === 1) { return $name; } $map = self::_oidReverseMap(); $k = mb_strtolower($name, '8bit'); if (! isset($map[$k])) { throw new OutOfBoundsException("No OID for {$name}."); } return $map[$k]; } /** * Get ASN.1 string for given attribute type. * * @param string $oid Attribute OID * @param string $str String */ public static function asn1StringForType(string $oid, string $str): StringType { if (! array_key_exists($oid, self::MAP_ATTR_TO_STR_TYPE)) { return UTF8String::create($str); } return PrintableString::create($str); } /** * Get name to OID lookup map. * * @return array */ private static function _oidReverseMap(): array { static $map; if (! isset($map)) { $map = []; // for each attribute type foreach (self::MAP_OID_TO_NAME as $oid => $names) { // for primary name and aliases foreach ($names as $name) { $map[mb_strtolower($name, '8bit')] = $oid; } } } return $map; } }