Пример #1
0
def _import_ldap_users_info(connection, user_info, sync_groups=False, import_by_dn=False):
  """
  Import user_info found through ldap_access.find_users.
  """
  imported_users = []
  for ldap_info in user_info:
    # Extra validation in case import by DN and username has spaces or colons
    validate_username(ldap_info['username'])

    user, created = ldap_access.get_or_create_ldap_user(username=ldap_info['username'])
    profile = get_profile(user)
    if not created and profile.creation_method == str(UserProfile.CreationMethod.HUE):
      # This is a Hue user, and shouldn't be overwritten
      LOG.warn(_('There was a naming conflict while importing user %(username)s') % {
        'username': ldap_info['username']
      })
      return None

    default_group = get_default_user_group()
    if created and default_group is not None:
      user.groups.add(default_group)

    if 'first' in ldap_info:
      user.first_name = ldap_info['first']
    if 'last' in ldap_info:
      user.last_name = ldap_info['last']
    if 'email' in ldap_info:
      user.email = ldap_info['email']

    profile.creation_method = UserProfile.CreationMethod.EXTERNAL
    profile.save()
    user.save()
    imported_users.append(user)

    # sync groups
    if sync_groups and 'groups' in ldap_info:
      old_groups = set(user.groups.all())
      new_groups = set()
      # Skip if 'memberOf' or 'isMemberOf' are not set
      for group_dn in ldap_info['groups']:
        group_ldap_info = connection.find_groups(group_dn, find_by_dn=True, scope=ldap.SCOPE_BASE)
        for group_info in group_ldap_info:
          # Add only if user isn't part of group.
          if not user.groups.filter(name=group_info['name']).exists():
            groups = import_ldap_groups(connection, group_info['dn'], import_members=False, import_members_recursive=False, sync_users=False, import_by_dn=True)
            if groups:
              new_groups.update(groups)

      # Remove out of date groups
      remove_groups = old_groups - new_groups
      remove_ldap_groups = LdapGroup.objects.filter(group__in=remove_groups)
      remove_groups_filtered = [ldapgroup.group for ldapgroup in remove_ldap_groups]
      user.groups.filter(group__in=remove_groups_filtered).delete()
      user.groups.add(*new_groups)
      Group.objects.filter(group__in=remove_groups_filtered).delete()
      remove_ldap_groups.delete()

  return imported_users
Пример #2
0
def _import_ldap_users_info(connection, user_info, sync_groups=False, import_by_dn=False):
  """
  Import user_info found through ldap_access.find_users.
  """
  imported_users = []
  for ldap_info in user_info:
    # Extra validation in case import by DN and username has spaces or colons
    validate_username(ldap_info['username'])

    user, created = ldap_access.get_or_create_ldap_user(username=ldap_info['username'])
    profile = get_profile(user)
    if not created and profile.creation_method == str(UserProfile.CreationMethod.HUE):
      # This is a Hue user, and shouldn't be overwritten
      LOG.warn(_('There was a naming conflict while importing user %(username)s') % {
        'username': ldap_info['username']
      })
      return None

    default_group = get_default_user_group()
    if created and default_group is not None:
      user.groups.add(default_group)

    if 'first' in ldap_info:
      user.first_name = ldap_info['first']
    if 'last' in ldap_info:
      user.last_name = ldap_info['last']
    if 'email' in ldap_info:
      user.email = ldap_info['email']

    profile.creation_method = UserProfile.CreationMethod.EXTERNAL
    profile.save()
    user.save()
    imported_users.append(user)

    # sync groups
    if sync_groups and 'groups' in ldap_info:
      old_groups = set(user.groups.all())
      new_groups = set()
      # Skip if 'memberOf' or 'isMemberOf' are not set
      for group_dn in ldap_info['groups']:
        group_ldap_info = connection.find_groups(group_dn, find_by_dn=True, scope=ldap.SCOPE_BASE)
        for group_info in group_ldap_info:
          # Add only if user isn't part of group.
          if not user.groups.filter(name=group_info['name']).exists():
            groups = import_ldap_groups(connection, group_info['dn'], import_members=False, import_members_recursive=False, sync_users=False, import_by_dn=True)
            if groups:
              new_groups.update(groups)

      # Remove out of date groups
      remove_groups = old_groups - new_groups
      remove_ldap_groups = LdapGroup.objects.filter(group__in=remove_groups)
      remove_groups_filtered = [ldapgroup.group for ldapgroup in remove_ldap_groups]
      user.groups.filter(group__in=remove_groups_filtered).delete()
      user.groups.add(*new_groups)
      Group.objects.filter(group__in=remove_groups_filtered).delete()
      remove_ldap_groups.delete()

  return imported_users
Пример #3
0
      def get_or_create_user(self, username, ldap_user):
        username = force_username_case(username)

        try:
          validate_username(username)

          if desktop.conf.LDAP.IGNORE_USERNAME_CASE.get():
            try:
              return User.objects.get(username__iexact=username), False
            except User.DoesNotExist:
              return User.objects.get_or_create(username=username)
          else:
            return User.objects.get_or_create(username=username)
        except ValidationError, e:
          LOG.exception("LDAP username is invalid: %s" % username)
Пример #4
0
      def get_or_create_user(self, username, ldap_user):
        username = force_username_case(username)

        try:
          #Avoid circular import from is_admin
          from useradmin.forms import validate_username
          validate_username(username)

          if LDAP.IGNORE_USERNAME_CASE.get():
            try:
              return User.objects.get(username__iexact=username), False
            except User.DoesNotExist:
              return User.objects.get_or_create(username=username)
          else:
            return User.objects.get_or_create(username=username)
        except ValidationError as e:
          LOG.exception("LDAP username is invalid: %s" % username)
Пример #5
0
      def get_or_create_user(self, username, ldap_user):
        username = force_username_case(username)

        try:
          #Avoid circular import from is_admin
          from useradmin.forms import validate_username
          validate_username(username)

          if desktop.conf.LDAP.IGNORE_USERNAME_CASE.get():
            try:
              return User.objects.get(username__iexact=username), False
            except User.DoesNotExist:
              return User.objects.get_or_create(username=username)
          else:
            return User.objects.get_or_create(username=username)
        except ValidationError, e:
          LOG.exception("LDAP username is invalid: %s" % username)
Пример #6
0
def _import_ldap_users_info(connection,
                            user_info,
                            sync_groups=False,
                            import_by_dn=False,
                            server=None):
    """
  Import user_info found through ldap_access.find_users.
  """
    imported_users = []

    for ldap_info in user_info:
        # Extra validation in case import by DN and username has spaces or colons
        try:
            validate_username(ldap_info['username'])

            user, created = ldap_access.get_or_create_ldap_user(
                username=ldap_info['username'])
            profile = get_profile(user)
            if not created and profile.creation_method == str(
                    UserProfile.CreationMethod.HUE):
                # This is a Hue user, and shouldn't be overwritten
                LOG.warn(
                    _('There was a naming conflict while importing user %(username)s'
                      ) % {'username': ldap_info['username']})
                return None

            default_group = get_default_user_group()
            if created and default_group is not None:
                user.groups.add(default_group)

            if 'first' in ldap_info:
                user.first_name = ldap_info['first']
            if 'last' in ldap_info:
                user.last_name = ldap_info['last']
            if 'email' in ldap_info:
                user.email = ldap_info['email']

            profile.creation_method = UserProfile.CreationMethod.EXTERNAL
            profile.save()
            user.save()
            imported_users.append(user)

            # sync groups
            if sync_groups:
                old_groups = set(user.groups.all())
                new_groups = set()
                current_ldap_groups = set()

                ldap_config = desktop.conf.LDAP.LDAP_SERVERS.get(
                )[server] if server else desktop.conf.LDAP
                group_member_attr = ldap_config.GROUPS.GROUP_MEMBER_ATTR.get()
                group_filter = ldap_config.GROUPS.GROUP_FILTER.get()
                # Search for groups based on group_member_attr=username and group_member_attr=dn
                # covers AD, Standard Ldap and posixAcount/posixGroup
                if not group_filter.startswith('('):
                    group_filter = '(' + group_filter + ')'

                # Sanitizing the DN before using in a Search filter
                sanitized_dn = ldap.filter.escape_filter_chars(
                    ldap_info['dn']).replace(r'\2a', r'*')
                sanitized_dn = sanitized_dn.replace(r'\5c,', r'\5c\2c')

                find_groups_filter = "(&" + group_filter + "(|(" + group_member_attr + "=" + ldap_info['username'] + ")(" + \
                                     group_member_attr + "=" + sanitized_dn + ")))"
                group_ldap_info = connection.find_groups(
                    "*", group_filter=find_groups_filter)
                for group_info in group_ldap_info:
                    if Group.objects.filter(name=group_info['name']).exists():
                        # Add only if user isn't part of group.
                        current_ldap_groups.add(
                            Group.objects.get(name=group_info['name']))
                        if not user.groups.filter(
                                name=group_info['name']).exists():
                            groups = import_ldap_groups(
                                connection,
                                group_info['dn'],
                                import_members=False,
                                import_members_recursive=False,
                                sync_users=True,
                                import_by_dn=True)
                            if groups:
                                new_groups.update(groups)
                # Remove out of date groups
                remove_groups = old_groups - current_ldap_groups
                remove_ldap_groups = LdapGroup.objects.filter(
                    group__in=remove_groups)
                remove_groups_filtered = [
                    ldapgroup.group for ldapgroup in remove_ldap_groups
                ]
                for group in remove_groups_filtered:
                    user.groups.remove(group)
                user.groups.add(*new_groups)
                Group.objects.filter(group__in=remove_groups_filtered).delete()
        except (AssertionError, RuntimeError) as e:
            LOG.warn('%s: %s' % (ldap_info['username'], e.message))

    return imported_users
Пример #7
0
def _import_ldap_users_info(connection, user_info, sync_groups=False, import_by_dn=False, server=None, failed_users=None):
  """
  Import user_info found through ldap_access.find_users.
  """
  imported_users = []

  for ldap_info in user_info:
    # Extra validation in case import by DN and username has spaces or colons
    try:
      validate_username(ldap_info['username'])

      user, created = ldap_access.get_or_create_ldap_user(username=ldap_info['username'])
      profile = get_profile(user)
      if not created and profile.creation_method == str(UserProfile.CreationMethod.HUE):
        # This is a Hue user, and shouldn't be overwritten
        LOG.warn(_('There was a naming conflict while importing user %(username)s') % {
          'username': ldap_info['username']
        })
        return None

      default_group = get_default_user_group()
      if created and default_group is not None:
        user.groups.add(default_group)

      if 'first' in ldap_info:
        validate_first_name(ldap_info['first'])
        user.first_name = ldap_info['first']
      if 'last' in ldap_info:
        validate_last_name(ldap_info['last'])
        user.last_name = ldap_info['last']
      if 'email' in ldap_info:
        user.email = ldap_info['email']

      profile.creation_method = UserProfile.CreationMethod.EXTERNAL
      profile.save()
      user.save()
      imported_users.append(user)

      # sync groups
      if sync_groups:
        old_groups = set(user.groups.all())
        new_groups = set()
        current_ldap_groups = set()

        ldap_config = desktop.conf.LDAP.LDAP_SERVERS.get()[server] if server else desktop.conf.LDAP
        group_member_attr = ldap_config.GROUPS.GROUP_MEMBER_ATTR.get()
        group_filter = ldap_config.GROUPS.GROUP_FILTER.get()
        # Search for groups based on group_member_attr=username and group_member_attr=dn
        # covers AD, Standard Ldap and posixAcount/posixGroup
        if not group_filter.startswith('('):
          group_filter = '(' + group_filter + ')'

        # Sanitizing the DN before using in a Search filter
        sanitized_dn = ldap.filter.escape_filter_chars(ldap_info['dn']).replace(r'\2a', r'*')
        sanitized_dn = sanitized_dn.replace(r'\5c,', r'\5c\2c')

        find_groups_filter = "(&" + group_filter + "(|(" + group_member_attr + "=" + ldap_info['username'] + ")(" + \
                             group_member_attr + "=" + sanitized_dn + ")))"
        group_ldap_info = connection.find_groups("*", group_filter=find_groups_filter)
        for group_info in group_ldap_info:
          if Group.objects.filter(name=group_info['name']).exists():
          # Add only if user isn't part of group.
            current_ldap_groups.add(Group.objects.get(name=group_info['name']))
            if not user.groups.filter(name=group_info['name']).exists():
              groups = import_ldap_groups(connection, group_info['dn'], import_members=False, import_members_recursive=False,
                                          sync_users=True, import_by_dn=True, failed_users=failed_users)
              if groups:
                new_groups.update(groups)
        # Remove out of date groups
        remove_groups = old_groups - current_ldap_groups
        remove_ldap_groups = LdapGroup.objects.filter(group__in=remove_groups)
        remove_groups_filtered = [ldapgroup.group for ldapgroup in remove_ldap_groups]
        for group in remove_groups_filtered:
          user.groups.remove(group)
        user.groups.add(*new_groups)
        Group.objects.filter(group__in=remove_groups_filtered).delete()
    except (ValidationError, LdapSearchException) as e:
      if failed_users is None:
        failed_users = []
      failed_users.append(ldap_info['username'])
      LOG.warn('Could not import %s: %s' % (ldap_info['username'], e.message))

  return imported_users
Пример #8
0
    # Sync users
    if sync_users:
      for member in members:
        user_info = []
        try:
          user_info = connection.find_users(member, find_by_dn=True)
        except LdapSearchException, e:
          LOG.warn("Failed to find LDAP user: %s" % e)

        if len(user_info) > 1:
          LOG.warn('Found multiple users for member %s.' % member)
        else:
          for ldap_info in user_info:
            try:
              validate_username(ldap_info['username'])
              user = ldap_access.get_ldap_user(username=ldap_info['username'])
              group.user_set.add(user)
            except ValidationError, e:
              if failed_users is None:
                failed_users = []
              failed_users.append(ldap_info['username'])
              LOG.warn('Could not sync %s: %s' % (ldap_info['username'], e.message))
            except User.DoesNotExist:
              pass

    # Import/fetch posix users and groups
    # Posix members
    if posix_members:
      if import_members:
        for posix_member in posix_members:
Пример #9
0
    # Sync users
    if sync_users:
      for member in members:
        user_info = []
        try:
          user_info = connection.find_users(member, find_by_dn=True)
        except LdapSearchException, e:
          LOG.warn("Failed to find LDAP user: %s" % e)

        if len(user_info) > 1:
          LOG.warn('Found multiple users for member %s.' % member)
        else:
          for ldap_info in user_info:
            try:
              validate_username(ldap_info['username'])
              user = ldap_access.get_ldap_user(username=ldap_info['username'])
              group.user_set.add(user)
            except ValidationError, e:
              if failed_users is None:
                failed_users = []
              failed_users.append(ldap_info['username'])
              LOG.warn('Could not sync %s: %s' % (ldap_info['username'], e.message))
            except User.DoesNotExist:
              pass

    # Import/fetch posix users and groups
    # Posix members
    if posix_members:
      if import_members:
        for posix_member in posix_members:
Пример #10
0
def _import_ldap_suboordinate_groups(connection, groupname_pattern, import_members=False, recursive_import_members=False,
                                     sync_users=True, import_by_dn=False):
  """
  Import a group from LDAP. If import_members is true, this will also import any
  LDAP users that exist within the group. This will use suboordinate group logic.
  A suboordinate group is a group that is a subentry of another group.
  e.g. CN=subtest,CN=test,OU=groups,DC=exampe,DC=COM is a suboordinate group of
  CN=test,OU=groups,DC=exampe,DC=COM
  """
  if import_by_dn:
    scope = ldap.SCOPE_BASE
  else:
    scope = ldap.SCOPE_SUBTREE
  group_info = connection.find_groups(groupname_pattern, find_by_dn=import_by_dn, scope=scope)

  if not group_info:
    LOG.warn("Could not get LDAP details for group pattern %s" % groupname_pattern)
    return None

  groups = []
  for ldap_info in group_info:
    group, created = Group.objects.get_or_create(name=ldap_info['name'])
    if not created and not LdapGroup.objects.filter(group=group).exists():
      # This is a Hue group, and shouldn't be overwritten
      LOG.warn(_('There was a naming conflict while importing group %(groupname)s in pattern %(groupname_pattern)s') % {
        'groupname': ldap_info['name'],
        'groupname_pattern': groupname_pattern
      })
      return None

    LdapGroup.objects.get_or_create(group=group)
    group.user_set.clear()

    # Find members and posix members for group and subgoups
    members = ldap_info['members']
    posix_members = ldap_info['posix_members']

    # @TODO: Deprecate recursive_import_members as it may not be useful.
    if import_members:
      if recursive_import_members:
        for sub_ldap_info in connection.find_groups(ldap_info['dn'], find_by_dn=True):
          members += sub_ldap_info['members']
          posix_members += sub_ldap_info['posix_members']

      for member in members:
        LOG.debug("Importing user %s" % smart_str(member))
        group.user_set.add( *( _import_ldap_users(connection, member, import_by_dn=True) or [] ) )

    # Sync users
    if sync_users:
      for member in members:
        user_info = connection.find_users(member, find_by_dn=True)
        if len(user_info) > 1:
          LOG.warn('Found multiple users for member %s.' % member)
        else:
          for ldap_info in user_info:
            try:
              validate_username(ldap_info['username'])
              user = ldap_access.get_ldap_user(username=ldap_info['username'])
              group.user_set.add(user)
            except (AssertionError, RuntimeError), e:
              LOG.warn('Could not sync %s: %s' % (ldap_info['username'], e.message))
            except User.DoesNotExist:
              pass
Пример #11
0
def _import_ldap_suboordinate_groups(connection,
                                     groupname_pattern,
                                     import_members=False,
                                     recursive_import_members=False,
                                     sync_users=True,
                                     import_by_dn=False):
    """
  Import a group from LDAP. If import_members is true, this will also import any
  LDAP users that exist within the group. This will use suboordinate group logic.
  A suboordinate group is a group that is a subentry of another group.
  e.g. CN=subtest,CN=test,OU=groups,DC=exampe,DC=COM is a suboordinate group of
  CN=test,OU=groups,DC=exampe,DC=COM
  """
    if import_by_dn:
        scope = ldap.SCOPE_BASE
    else:
        scope = ldap.SCOPE_SUBTREE
    group_info = connection.find_groups(groupname_pattern,
                                        find_by_dn=import_by_dn,
                                        scope=scope)

    if not group_info:
        LOG.warn("Could not get LDAP details for group pattern %s" %
                 groupname_pattern)
        return None

    groups = []
    for ldap_info in group_info:
        group, created = Group.objects.get_or_create(name=ldap_info['name'])
        if not created and not LdapGroup.objects.filter(group=group).exists():
            # This is a Hue group, and shouldn't be overwritten
            LOG.warn(
                _('There was a naming conflict while importing group %(groupname)s in pattern %(groupname_pattern)s'
                  ) % {
                      'groupname': ldap_info['name'],
                      'groupname_pattern': groupname_pattern
                  })
            return None

        LdapGroup.objects.get_or_create(group=group)
        group.user_set.clear()

        # Find members and posix members for group and subgoups
        members = ldap_info['members']
        posix_members = ldap_info['posix_members']

        # @TODO: Deprecate recursive_import_members as it may not be useful.
        if import_members:
            if recursive_import_members:
                for sub_ldap_info in connection.find_groups(ldap_info['dn'],
                                                            find_by_dn=True):
                    members += sub_ldap_info['members']
                    posix_members += sub_ldap_info['posix_members']

            for member in members:
                LOG.debug("Importing user %s" % smart_str(member))
                group.user_set.add(
                    *(_import_ldap_users(connection, member, import_by_dn=True)
                      or []))

        # Sync users
        if sync_users:
            for member in members:
                user_info = connection.find_users(member, find_by_dn=True)
                if len(user_info) > 1:
                    LOG.warn('Found multiple users for member %s.' % member)
                else:
                    for ldap_info in user_info:
                        try:
                            validate_username(ldap_info['username'])
                            user = ldap_access.get_ldap_user(
                                username=ldap_info['username'])
                            group.user_set.add(user)
                        except (AssertionError, RuntimeError), e:
                            LOG.warn('Could not sync %s: %s' %
                                     (ldap_info['username'], e.message))
                        except User.DoesNotExist:
                            pass