Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def make_bytearray(value, encoding=None):
if str is bytes: # python 2
if isinstance(value, unicode):
return value.encode(encoding)
else:
return bytearray(value)
else:
if isinstance(value, SEQUENCE_TYPES):
return bytearray(value)
else:
return bytearray(value, encoding)
def ad_remove_members_from_groups(connection,
members_dn,
groups_dn,
fix):
"""
:param connection: a bound Connection object
:param members_dn: the list of members to remove from groups
:param groups_dn: the list of groups where members are to be removed
:param fix: checks for group existence and existing members
:return: a boolean where True means that the operation was successful and False means an error has happened
Removes users-groups relations following the Activwe Directory rules: users are removed from groups' member attribute
"""
if not isinstance(members_dn, SEQUENCE_TYPES):
members_dn = [members_dn]
if not isinstance(groups_dn, SEQUENCE_TYPES):
groups_dn = [groups_dn]
if connection.check_names: # builds new lists with sanitized dn
safe_members_dn = []
safe_groups_dn = []
for member_dn in members_dn:
safe_members_dn.append(safe_dn(member_dn))
for group_dn in groups_dn:
safe_groups_dn.append(safe_dn(group_dn))
members_dn = safe_members_dn
groups_dn = safe_groups_dn
groups_dn,
fix=True):
"""
:param connection: a bound Connection object
:param members_dn: the list of members to add to groups
:param groups_dn: the list of groups where members are to be added
:param fix: checks for group existence and already assigned members
:return: a boolean where True means that the operation was successful and False means an error has happened
Establishes users-groups relations following the Active Directory rules: users are added to the member attribute of groups.
Raises LDAPInvalidDnError if members or groups are not found in the DIT.
"""
if not isinstance(members_dn, SEQUENCE_TYPES):
members_dn = [members_dn]
if not isinstance(groups_dn, SEQUENCE_TYPES):
groups_dn = [groups_dn]
error = False
for group in groups_dn:
if fix: # checks for existance of group and for already assigned members
result = connection.search(group, '(objectclass=*)', BASE, dereference_aliases=DEREF_NEVER, attributes=['member'])
if not connection.strategy.sync:
response, result = connection.get_response(result)
else:
response, result = connection.response, connection.result
if not result['description'] == 'success':
raise LDAPInvalidDnError(group + ' not found')
existing_members = response[0]['attributes']['member'] if 'member' in response[0]['attributes'] else []
def safe_dn(dn, decompose=False, reverse=False):
"""
normalize and escape a dn, if dn is a sequence it is joined.
the reverse parameter changes the join direction of the sequence
"""
if isinstance(dn, SEQUENCE_TYPES):
components = [rdn for rdn in dn]
if reverse:
dn = ','.join(reversed(components))
else:
dn = ','.join(components)
if decompose:
escaped_dn = []
else:
escaped_dn = ''
if dn.startswith(''): # Active Directory allows looking up objects by putting its GUID in a specially-formatted DN (e.g. '')
escaped_dn = dn
elif '@' not in dn: # active directory UPN (User Principal Name) consist of an account, the at sign (@) and a domain, or the domain level logn name domain\username
for component in parse_dn(dn, escape=True):
if decompose:
escaped_dn.append((component[0], component[1], component[2]))
if isinstance(_UTF8_ENCODED_SYNTAXES, SEQUENCE_TYPES):
return _UTF8_ENCODED_SYNTAXES
else:
return [_UTF8_ENCODED_SYNTAXES]
elif parameter == 'UTF8_ENCODED_TYPES': # Sequence
if isinstance(_UTF8_ENCODED_TYPES, SEQUENCE_TYPES):
return _UTF8_ENCODED_TYPES
else:
return [_UTF8_ENCODED_TYPES]
elif parameter in ['ADDITIONAL_SERVER_ENCODINGS', 'ADDITIONAL_ENCODINGS']: # Sequence - ADDITIONAL_ENCODINGS for backward compatibility
if isinstance(_ADDITIONAL_SERVER_ENCODINGS, SEQUENCE_TYPES):
return _ADDITIONAL_SERVER_ENCODINGS
else:
return [_ADDITIONAL_SERVER_ENCODINGS]
elif parameter in ['ADDITIONAL_CLIENT_ENCODINGS']: # Sequence
if isinstance(_ADDITIONAL_CLIENT_ENCODINGS, SEQUENCE_TYPES):
return _ADDITIONAL_CLIENT_ENCODINGS
else:
return [_ADDITIONAL_CLIENT_ENCODINGS]
elif parameter == 'IGNORE_MALFORMED_SCHEMA': # Boolean
return _IGNORE_MALFORMED_SCHEMA
elif parameter == 'ATTRIBUTES_EXCLUDED_FROM_OBJECT_DEF': # Sequence
if isinstance(_ATTRIBUTES_EXCLUDED_FROM_OBJECT_DEF, SEQUENCE_TYPES):
return _ATTRIBUTES_EXCLUDED_FROM_OBJECT_DEF
else:
return [_ATTRIBUTES_EXCLUDED_FROM_OBJECT_DEF]
elif parameter == 'IGNORED_MANDATORY_ATTRIBUTES_IN_OBJECT_DEF': # Sequence
if isinstance(_IGNORED_MANDATORY_ATTRIBUTES_IN_OBJECT_DEF, SEQUENCE_TYPES):
return _IGNORED_MANDATORY_ATTRIBUTES_IN_OBJECT_DEF
else:
return [_IGNORED_MANDATORY_ATTRIBUTES_IN_OBJECT_DEF]
if log_enabled(BASIC):
log(BASIC, 'start ADD operation via <%s>', self)
self.last_error = None
_attributes = deepcopy(attributes) # dict could change when adding objectClass values
if self.check_names:
dn = safe_dn(dn)
if log_enabled(EXTENDED):
log(EXTENDED, 'dn sanitized to <%s> for ADD operation via <%s>', dn, self)
with self.connection_lock:
self._fire_deferred()
attr_object_class = []
if object_class is None:
parm_object_class = []
else:
parm_object_class = list(object_class) if isinstance(object_class, SEQUENCE_TYPES) else [object_class]
object_class_attr_name = ''
if _attributes:
for attr in _attributes:
if attr.lower() == 'objectclass':
object_class_attr_name = attr
attr_object_class = list(_attributes[object_class_attr_name]) if isinstance(_attributes[object_class_attr_name], SEQUENCE_TYPES) else [_attributes[object_class_attr_name]]
break
else:
_attributes = dict()
if not object_class_attr_name:
object_class_attr_name = 'objectClass'
attr_object_class = [to_unicode(object_class) for object_class in attr_object_class] # converts objectclass to unicode in case of bytes value
_attributes[object_class_attr_name] = reduce(lambda x, y: x + [y] if y not in x else x, parm_object_class + attr_object_class, []) # remove duplicate ObjectClasses
def _get_schema_info(self, connection, entry=''):
"""
Retrieve schema from subschemaSubentry DSE attribute, per RFC
4512 (4.4 and 5.1); entry = '' means DSE.
"""
if connection.strategy.no_real_dsa: # do not try for mock strategies
return
schema_entry = None
if self._dsa_info and entry == '': # subschemaSubentry already present in dsaInfo
if isinstance(self._dsa_info.schema_entry, SEQUENCE_TYPES):
schema_entry = self._dsa_info.schema_entry[0] if self._dsa_info.schema_entry else None
else:
schema_entry = self._dsa_info.schema_entry if self._dsa_info.schema_entry else None
else:
result = connection.search(entry, '(objectClass=*)', BASE, attributes=['subschemaSubentry'], get_operational_attributes=True)
if isinstance(result, bool): # sync request
if result and 'subschemaSubentry' in connection.response[0]['raw_attributes']:
if len(connection.response[0]['raw_attributes']['subschemaSubentry']) > 0:
schema_entry = connection.response[0]['raw_attributes']['subschemaSubentry'][0]
else: # asynchronous request, must check if subschemaSubentry in attributes
results, _ = connection.get_response(result)
if len(results) == 1 and 'raw_attributes' in results[0] and 'subschemaSubentry' in results[0]['attributes']:
if len(results[0]['raw_attributes']['subschemaSubentry']) > 0:
schema_entry = results[0]['raw_attributes']['subschemaSubentry'][0]
if schema_entry and not connection.strategy.pooled: # in pooled strategies get_schema_info is performed by the worker threads
def check_json_dict(json_dict):
# needed for python 2
for k, v in json_dict.items():
if isinstance(v, dict):
check_json_dict(v)
elif isinstance(v, CaseInsensitiveDict):
check_json_dict(v._store)
elif isinstance(v, SEQUENCE_TYPES):
for i, e in enumerate(v):
if isinstance(e, dict):
check_json_dict(e)
elif isinstance(e, CaseInsensitiveDict):
check_json_dict(e._store)
else:
v[i] = format_json(e)
else:
json_dict[k] = format_json(v)
used_attribute_names = []
for attr_def in attr_defs:
name = None
for attr_name in response['attributes']:
if attr_def.name.lower() == attr_name.lower():
name = attr_name
break
if name or attr_def.default != NotImplemented: # attribute value found in result or default value present
attribute = Attribute(attr_def, entry)
attribute.__dict__['_response'] = response
attribute.__dict__['raw_values'] = response['raw_attributes'][name] if name else None
if attr_def.post_query and attr_def.name in response['attributes']:
attribute.__dict__['values'] = attr_def.post_query(attr_def.key, response['attributes'][name])
else:
attribute.__dict__['values'] = response['attributes'][name] if name else (attr_def.default if isinstance(attr_def.default, SEQUENCE_TYPES) else [attr_def.default])
if not isinstance(attribute.__dict__['values'], list): # force attribute values to list (if attribute is single-valued)
attribute.__dict__['values'] = [attribute.__dict__['values']]
if attr_def.dereference_dn: # try to get object referenced in value
# noinspection PyUnresolvedReferences
if attribute.values:
temp_reader = Reader(self.connection, attr_def.dereference_dn, query='', base='', get_operational_attributes=self.get_operational_attributes, controls=self.controls)
temp_values = []
# noinspection PyUnresolvedReferences
for element in attribute.values:
temp_values.append(temp_reader.search_object(element))
del temp_reader # remove the temporary Reader
attribute.__dict__['values'] = temp_values
# noinspection PyUnresolvedReferences
attributes[attribute.key] = attribute
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