/usr/lib/python3/dist-packages/ldap3/protocol/formatters/standard.py is in python3-ldap3 2.4.1-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 | """
"""
# Created on 2014.10.28
#
# Author: Giovanni Cannata
#
# Copyright 2014 - 2018 Giovanni Cannata
#
# This file is part of ldap3.
#
# ldap3 is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# ldap3 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with ldap3 in the COPYING and COPYING.LESSER files.
# If not, see <http://www.gnu.org/licenses/>.
from ... import SEQUENCE_TYPES
from .formatters import format_ad_timestamp, format_binary, format_boolean,\
format_integer, format_sid, format_time, format_unicode, format_uuid, format_uuid_le
from .validators import validate_integer, validate_time, always_valid,\
validate_generic_single_value, validate_boolean, validate_ad_timestamp,\
validate_uuid_le, validate_uuid, validate_minus_one
# for each syntax can be specified a format function and a input validation function
standard_formatter = {
'1.2.840.113556.1.4.903': (format_binary, None), # Object (DN-binary) - Microsoft
'1.2.840.113556.1.4.904': (format_unicode, None), # Object (DN-string) - Microsoft
'1.2.840.113556.1.4.905': (format_unicode, None), # String (Teletex) - Microsoft
'1.2.840.113556.1.4.906': (format_integer, validate_integer), # Large integer - Microsoft
'1.2.840.113556.1.4.907': (format_binary, None), # String (NT-sec-desc) - Microsoft
'1.2.840.113556.1.4.1221': (format_binary, None), # Object (OR-name) - Microsoft
'1.2.840.113556.1.4.1362': (format_unicode, None), # String (Case) - Microsoft
'1.3.6.1.4.1.1466.115.121.1.1': (format_binary, None), # ACI item [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.2': (format_binary, None), # Access point [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.3': (format_unicode, None), # Attribute type description
'1.3.6.1.4.1.1466.115.121.1.4': (format_binary, None), # Audio [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.5': (format_binary, None), # Binary [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.6': (format_unicode, None), # Bit String
'1.3.6.1.4.1.1466.115.121.1.7': (format_boolean, validate_boolean), # Boolean
'1.3.6.1.4.1.1466.115.121.1.8': (format_binary, None), # Certificate [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.9': (format_binary, None), # Certificate List [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.10': (format_binary, None), # Certificate Pair [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.11': (format_unicode, None), # Country String
'1.3.6.1.4.1.1466.115.121.1.12': (format_unicode, None), # Distinguished name (DN)
'1.3.6.1.4.1.1466.115.121.1.13': (format_binary, None), # Data Quality Syntax [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.14': (format_unicode, None), # Delivery method
'1.3.6.1.4.1.1466.115.121.1.15': (format_unicode, None), # Directory string
'1.3.6.1.4.1.1466.115.121.1.16': (format_unicode, None), # DIT Content Rule Description
'1.3.6.1.4.1.1466.115.121.1.17': (format_unicode, None), # DIT Structure Rule Description
'1.3.6.1.4.1.1466.115.121.1.18': (format_binary, None), # DL Submit Permission [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.19': (format_binary, None), # DSA Quality Syntax [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.20': (format_binary, None), # DSE Type [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.21': (format_binary, None), # Enhanced Guide
'1.3.6.1.4.1.1466.115.121.1.22': (format_unicode, None), # Facsimile Telephone Number
'1.3.6.1.4.1.1466.115.121.1.23': (format_binary, None), # Fax
'1.3.6.1.4.1.1466.115.121.1.24': (format_time, validate_time), # Generalized time
'1.3.6.1.4.1.1466.115.121.1.25': (format_binary, None), # Guide [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.26': (format_unicode, None), # IA5 string
'1.3.6.1.4.1.1466.115.121.1.27': (format_integer, validate_integer), # Integer
'1.3.6.1.4.1.1466.115.121.1.28': (format_binary, None), # JPEG
'1.3.6.1.4.1.1466.115.121.1.29': (format_binary, None), # Master and Shadow Access Points [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.30': (format_unicode, None), # Matching rule description
'1.3.6.1.4.1.1466.115.121.1.31': (format_unicode, None), # Matching rule use description
'1.3.6.1.4.1.1466.115.121.1.32': (format_unicode, None), # Mail Preference [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.33': (format_unicode, None), # MHS OR Address [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.34': (format_unicode, None), # Name and optional UID
'1.3.6.1.4.1.1466.115.121.1.35': (format_unicode, None), # Name form description
'1.3.6.1.4.1.1466.115.121.1.36': (format_unicode, None), # Numeric string
'1.3.6.1.4.1.1466.115.121.1.37': (format_unicode, None), # Object class description
'1.3.6.1.4.1.1466.115.121.1.38': (format_unicode, None), # OID
'1.3.6.1.4.1.1466.115.121.1.39': (format_unicode, None), # Other mailbox
'1.3.6.1.4.1.1466.115.121.1.40': (format_binary, None), # Octet string
'1.3.6.1.4.1.1466.115.121.1.41': (format_unicode, None), # Postal address
'1.3.6.1.4.1.1466.115.121.1.42': (format_binary, None), # Protocol Information [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.43': (format_binary, None), # Presentation Address [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.44': (format_unicode, None), # Printable string
'1.3.6.1.4.1.1466.115.121.1.45': (format_binary, None), # Subtree specification [OBSOLETE
'1.3.6.1.4.1.1466.115.121.1.46': (format_binary, None), # Supplier Information [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.47': (format_binary, None), # Supplier Or Consumer [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.48': (format_binary, None), # Supplier And Consumer [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.49': (format_binary, None), # Supported Algorithm [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.50': (format_unicode, None), # Telephone number
'1.3.6.1.4.1.1466.115.121.1.51': (format_unicode, None), # Teletex terminal identifier
'1.3.6.1.4.1.1466.115.121.1.52': (format_unicode, None), # Teletex number
'1.3.6.1.4.1.1466.115.121.1.53': (format_time, validate_time), # Utc time (deprecated)
'1.3.6.1.4.1.1466.115.121.1.54': (format_unicode, None), # LDAP syntax description
'1.3.6.1.4.1.1466.115.121.1.55': (format_binary, None), # Modify rights [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.56': (format_binary, None), # LDAP Schema Definition [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.57': (format_unicode, None), # LDAP Schema Description [OBSOLETE]
'1.3.6.1.4.1.1466.115.121.1.58': (format_unicode, None), # Substring assertion
'1.3.6.1.1.16.1': (format_uuid, validate_uuid), # UUID
'2.16.840.1.113719.1.1.4.1.501': (format_uuid, None), # GUID (Novell)
'2.16.840.1.113719.1.1.5.1.0': (format_binary, None), # Unknown (Novell)
'2.16.840.1.113719.1.1.5.1.6': (format_unicode, None), # Case Ignore List (Novell)
'2.16.840.1.113719.1.1.5.1.12': (format_binary, None), # Tagged Data (Novell)
'2.16.840.1.113719.1.1.5.1.13': (format_binary, None), # Octet List (Novell)
'2.16.840.1.113719.1.1.5.1.14': (format_unicode, None), # Tagged String (Novell)
'2.16.840.1.113719.1.1.5.1.15': (format_unicode, None), # Tagged Name And String (Novell)
'2.16.840.1.113719.1.1.5.1.16': (format_binary, None), # NDS Replica Pointer (Novell)
'2.16.840.1.113719.1.1.5.1.17': (format_unicode, None), # NDS ACL (Novell)
'2.16.840.1.113719.1.1.5.1.19': (format_time, validate_time), # NDS Timestamp (Novell)
'2.16.840.1.113719.1.1.5.1.22': (format_integer, validate_integer), # Counter (Novell)
'2.16.840.1.113719.1.1.5.1.23': (format_unicode, None), # Tagged Name (Novell)
'2.16.840.1.113719.1.1.5.1.25': (format_unicode, None), # Typed Name (Novell)
'supportedldapversion': (format_integer, None), # supportedLdapVersion (Microsoft)
'octetstring': (format_binary, validate_uuid_le), # octect string (Microsoft)
'1.2.840.113556.1.4.2': (format_uuid_le, None), # object guid (Microsoft)
'1.2.840.113556.1.4.13': (format_ad_timestamp, validate_ad_timestamp), # builtinCreationTime (Microsoft)
'1.2.840.113556.1.4.26': (format_ad_timestamp, validate_ad_timestamp), # creationTime (Microsoft)
'1.2.840.113556.1.4.49': (format_ad_timestamp, validate_ad_timestamp), # badPasswordTime (Microsoft)
'1.2.840.113556.1.4.51': (format_ad_timestamp, validate_ad_timestamp), # lastLogoff (Microsoft)
'1.2.840.113556.1.4.52': (format_ad_timestamp, validate_ad_timestamp), # lastLogon (Microsoft)
'1.2.840.113556.1.4.96': (format_ad_timestamp, validate_minus_one), # pwdLastSet (Microsoft, can be set to -1 only)
'1.2.840.113556.1.4.146': (format_sid, None), # objectSid (Microsoft)
'1.2.840.113556.1.4.159': (format_ad_timestamp, validate_ad_timestamp), # accountExpires (Microsoft)
'1.2.840.113556.1.4.662': (format_ad_timestamp, validate_ad_timestamp), # lockoutTime (Microsoft)
'1.2.840.113556.1.4.1696': (format_ad_timestamp, validate_ad_timestamp) # lastLogonTimestamp (Microsoft)
}
def find_attribute_helpers(attr_type, name, custom_formatter):
"""
Tries to format following the OIDs info and format_helper specification.
Search for attribute oid, then attribute name (can be multiple), then attribute syntax
Precedence is:
1. attribute name
2. attribute oid(from schema)
3. attribute names (from oid_info)
4. attribute syntax (from schema)
Custom formatters can be defined in Server object and have precedence over the standard_formatters
If no formatter is found the raw_value is returned as bytes.
Attributes defined as SINGLE_VALUE in schema are returned as a single object, otherwise are returned as a list of object
Formatter functions can return any kind of object
return a tuple (formatter, validator)
"""
formatter = None
if custom_formatter and isinstance(custom_formatter, dict): # if custom formatters are defined they have precedence over the standard formatters
if name in custom_formatter: # search for attribute name, as returned by the search operation
formatter = custom_formatter[name]
if not formatter and attr_type and attr_type.oid in custom_formatter: # search for attribute oid as returned by schema
formatter = custom_formatter[attr_type.oid]
if not formatter and attr_type and attr_type.oid_info:
if isinstance(attr_type.oid_info[2], SEQUENCE_TYPES): # search for multiple names defined in oid_info
for attr_name in attr_type.oid_info[2]:
if attr_name in custom_formatter:
formatter = custom_formatter[attr_name]
break
elif attr_type.oid_info[2] in custom_formatter: # search for name defined in oid_info
formatter = custom_formatter[attr_type.oid_info[2]]
if not formatter and attr_type and attr_type.syntax in custom_formatter: # search for syntax defined in schema
formatter = custom_formatter[attr_type.syntax]
if not formatter and name in standard_formatter: # search for attribute name, as returned by the search operation
formatter = standard_formatter[name]
if not formatter and attr_type and attr_type.oid in standard_formatter: # search for attribute oid as returned by schema
formatter = standard_formatter[attr_type.oid]
if not formatter and attr_type and attr_type.oid_info:
if isinstance(attr_type.oid_info[2], SEQUENCE_TYPES): # search for multiple names defined in oid_info
for attr_name in attr_type.oid_info[2]:
if attr_name in standard_formatter:
formatter = standard_formatter[attr_name]
break
elif attr_type.oid_info[2] in standard_formatter: # search for name defined in oid_info
formatter = standard_formatter[attr_type.oid_info[2]]
if not formatter and attr_type and attr_type.syntax in standard_formatter: # search for syntax defined in schema
formatter = standard_formatter[attr_type.syntax]
if formatter is None:
return None, None
return formatter
def format_attribute_values(schema, name, values, custom_formatter):
if not values: # RFCs states that attributes must always have values, but a flaky server returns empty values too
return []
if schema and schema.attribute_types and name in schema.attribute_types:
attr_type = schema.attribute_types[name]
else:
attr_type = None
attribute_helpers = find_attribute_helpers(attr_type, name, custom_formatter)
if not isinstance(attribute_helpers, tuple): # custom formatter
formatter = attribute_helpers
else:
formatter = format_unicode if not attribute_helpers[0] else attribute_helpers[0]
formatted_values = [formatter(raw_value) for raw_value in values] # executes formatter
if formatted_values:
return formatted_values[0] if (attr_type and attr_type.single_value) else formatted_values
else: # RFCs states that attributes must always have values, but AD return empty values in DirSync
return []
def find_attribute_validator(schema, name, custom_validator):
if schema and schema.attribute_types and name in schema.attribute_types:
attr_type = schema.attribute_types[name]
else:
attr_type = None
attribute_helpers = find_attribute_helpers(attr_type, name, custom_validator)
if not isinstance(attribute_helpers, tuple): # custom validator
validator = attribute_helpers
else:
if not attribute_helpers[1]:
if attr_type and attr_type.single_value:
validator = validate_generic_single_value # validate only single value
else:
validator = always_valid # unknown syntax, accepts single and multi value
else:
validator = attribute_helpers[1]
return validator
|