예제 #1
0
  protected Set<Entry> resolveNestedRoles(
      final Tuple<String, Dn> role, final LdapConnection ldapConnection, final String roleName)
      throws AuthException, LdapException {

    EntryCursor rolesResult = null;
    EntryCursor _result = null;
    try {

      final Set<Entry> result = new HashSet<Entry>();
      Dn roleDn = null;
      final boolean isRoleStringValidDn = Dn.isValid(role.v1());

      if (role.v2() != null) {
        roleDn = role.v2();
      } else {
        // lookup role
        if (isRoleStringValidDn) {
          roleDn = ldapConnection.lookup(role.v1()).getDn();
        } else {

          try {

            // search
            _result =
                ldapConnection.search(
                    settings.get(
                        ConfigConstants.ARMOR_AUTHENTICATION_AUTHORIZATION_LDAP_ROLEBASE, ""),
                    settings
                        .get(
                            ConfigConstants.ARMOR_AUTHENTICATION_AUTHORIZATION_LDAP_ROLESEARCH,
                            "(member={0})")
                        .replace("{1}", role.v1()),
                    SearchScope.SUBTREE);

            // one
            if (!_result.next()) {
              log.warn("Cannot resolve role '{}' (NOT FOUND)", role.v1());
            } else {

              //
              final Entry entry = _result.get();
              roleDn = entry.getDn();

              if (_result.next()) {
                log.warn("Cannot resolve role '{}' (MORE THAN ONE FOUND)", role.v1());
              }
            }
          } catch (final CursorException e) {
            log.warn("Cannot resolve role '{}' (EXCEPTION: {})", e, role.v1(), e.toString());
          } finally {
            if (_result != null) {
              _result.close();
            }
          }
        }
      }

      log.trace("role dn resolved to {}", roleDn);

      rolesResult =
          ldapConnection.search(
              settings.get(ConfigConstants.ARMOR_AUTHENTICATION_AUTHORIZATION_LDAP_ROLEBASE, ""),
              settings
                  .get(
                      ConfigConstants.ARMOR_AUTHENTICATION_AUTHORIZATION_LDAP_ROLESEARCH,
                      "(member={0})")
                  .replace("{0}", roleDn == null ? role.v1() : roleDn.toString())
                  .replace("{1}", role.v1()),
              SearchScope.SUBTREE);

      for (final Iterator iterator = rolesResult.iterator(); iterator.hasNext(); ) {
        final Entry searchResultEntry = (Entry) iterator.next();
        final String _role = searchResultEntry.get(roleName).getString();
        log.trace("nested l1 {}", searchResultEntry.getDn());
        final Set<Entry> in =
            resolveNestedRoles(
                new Tuple<String, Dn>(_role, searchResultEntry.getDn()), ldapConnection, roleName);

        for (final Iterator<Entry> iterator2 = in.iterator(); iterator2.hasNext(); ) {
          final Entry entry = iterator2.next();
          result.add(entry);
          log.trace("nested l2 {}", entry.getDn());
        }

        result.add(searchResultEntry);
      }

      return result;
    } finally {

      if (rolesResult != null) {
        rolesResult.close();
      }
    }
  }
  /**
   * adds mandatory operational attributes {@link #MANDATORY_ENTRY_ATOP_MAP} and updates all the
   * LDIF files. WARN: this method is only called for the first time when schema and config files
   * are bootstrapped afterwards it is the responsibility of the user to ensure correctness of LDIF
   * files if modified by hand
   *
   * <p>Note: we do these modifications explicitly cause we have no idea if each entry's LDIF file
   * has the correct values for all these mandatory attributes
   *
   * @param partition instance of the partition Note: should only be those which are loaded before
   *     starting the DirectoryService
   * @param dirService the DirectoryService instance
   * @throws Exception
   */
  public void updateMandatoryOpAttributes(Partition partition, DirectoryService dirService)
      throws Exception {
    CoreSession session = dirService.getAdminSession();

    String adminDn = session.getEffectivePrincipal().getName();

    ExprNode filter = new PresenceNode(SchemaConstants.OBJECT_CLASS_AT);

    AttributeType uuidAtT =
        schemaManager.lookupAttributeTypeRegistry(SchemaConstants.ENTRY_UUID_AT);
    AttributeType atTypeT = schemaManager.lookupAttributeTypeRegistry(SchemaConstants.ENTRY_CSN_AT);
    AttributeType creatorAtT =
        schemaManager.lookupAttributeTypeRegistry(SchemaConstants.CREATORS_NAME_AT);
    AttributeType createdTimeAtT =
        schemaManager.lookupAttributeTypeRegistry(SchemaConstants.CREATE_TIMESTAMP_AT);

    //        HashSet<AttributeTypeOptions> options = new HashSet<AttributeTypeOptions>(
    // MANDATORY_ENTRY_ATOP_MAP.values());
    /*


            AttributeType at;
            at
            //
            String id = SchemaUtils.stripOptions( returnAttribute );
            Set<String> options = SchemaUtils.getOptions( returnAttribute );

            AttributeType attributeType = session.getDirectoryService()
                .getSchemaManager().lookupAttributeTypeRegistry( id );
            AttributeTypeOptions attrOptions = new AttributeTypeOptions( attributeType, options );
    //

            EntryFilteringCursor cursor = session.search( partition.getSuffixDn(), SearchScope.SUBTREE, filter,
                AliasDerefMode.NEVER_DEREF_ALIASES, new HashSet<AttributeTypeOptions>( MANDATORY_ENTRY_ATOP_MAP.values() ) );
            cursor.beforeFirst();
    		 */
    EntryFilteringCursor cursor =
        session.search(
            partition.getSuffixDn(),
            SearchScope.SUBTREE,
            filter,
            AliasDerefMode.NEVER_DEREF_ALIASES,
            SchemaConstants.OBJECT_CLASS_AT_OID,
            SchemaConstants.ENTRY_UUID_AT_OID,
            SchemaConstants.ENTRY_CSN_AT_OID,
            SchemaConstants.CREATORS_NAME_AT_OID,
            SchemaConstants.CREATORS_NAME_AT_OID);
    cursor.beforeFirst();

    List<Modification> mods = new ArrayList<Modification>();

    while (cursor.next()) {
      Entry entry = cursor.get();

      Attribute uuidAt = entry.get(uuidAtT);
      String uuid = (uuidAt == null ? null : uuidAt.getString());

      if (!uuidChecker.isValidSyntax(uuid)) {
        uuidAt = new DefaultAttribute(uuidAtT, UUID.randomUUID().toString());
      }

      Modification uuidMod =
          new DefaultModification(ModificationOperation.REPLACE_ATTRIBUTE, uuidAt);
      mods.add(uuidMod);

      Attribute csnAt = entry.get(atTypeT);
      String csn = (csnAt == null ? null : csnAt.getString());

      if (!csnChecker.isValidSyntax(csn)) {
        csnAt = new DefaultAttribute(atTypeT, dirService.getCSN().toString());
      }

      Modification csnMod = new DefaultModification(ModificationOperation.REPLACE_ATTRIBUTE, csnAt);
      mods.add(csnMod);

      Attribute creatorAt = entry.get(creatorAtT);
      String creator = (creatorAt == null ? "" : creatorAt.getString().trim());

      if ((creator.length() == 0) || (!Dn.isValid(creator))) {
        creatorAt = new DefaultAttribute(creatorAtT, adminDn);
      }

      Modification creatorMod =
          new DefaultModification(ModificationOperation.REPLACE_ATTRIBUTE, creatorAt);
      mods.add(creatorMod);

      Attribute createdTimeAt = entry.get(createdTimeAtT);
      String createdTime = (createdTimeAt == null ? null : createdTimeAt.getString());

      if (!timeChecker.isValidSyntax(createdTime)) {
        createdTimeAt = new DefaultAttribute(createdTimeAtT, DateUtils.getGeneralizedTime());
      }

      Modification createdMod =
          new DefaultModification(ModificationOperation.REPLACE_ATTRIBUTE, createdTimeAt);
      mods.add(createdMod);

      if (!mods.isEmpty()) {
        LOG.debug(
            "modifying the entry {} after adding missing manadatory operational attributes",
            entry.getDn());
        ModifyOperationContext modifyContext = new ModifyOperationContext(session);
        modifyContext.setEntry(entry);
        modifyContext.setDn(entry.getDn());
        modifyContext.setModItems(mods);
        partition.modify(modifyContext);
      }

      mods.clear();
    }

    cursor.close();
  }
예제 #3
0
  @Override
  public void fillRoles(final User user, final AuthCredentials optionalAuthCreds)
      throws AuthException {

    final String authenticatedUser = user.getName();

    if (optionalAuthCreds != null) {
      optionalAuthCreds.clear();
    }

    Entry entry = null;
    String dn = null;
    EntryCursor result = null;
    EntryCursor rolesResult = null;
    LdapConnection ldapConnection = null;

    try {

      ldapConnection = getConnection(settings);

      final String bindDn = settings.get(ConfigConstants.ARMOR_AUTHENTICATION_LDAP_BIND_DN, null);

      if (bindDn != null) {
        ldapConnection.bind(
            bindDn, settings.get(ConfigConstants.ARMOR_AUTHENTICATION_LDAP_PASSWORD, null));
      } else {
        ldapConnection.anonymousBind();
      }

      if (Dn.isValid(authenticatedUser)) {
        // assume dn
        log.trace("{} is a valid DN", authenticatedUser);
        entry = ldapConnection.lookup(authenticatedUser);

        if (entry == null) {
          throw new AuthException("No user '" + authenticatedUser + "' found");
        }

      } else {

        // TODO FUTURE all ldap searches: follow referrals
        result =
            ldapConnection.search(
                settings.get(ConfigConstants.ARMOR_AUTHENTICATION_LDAP_USERBASE, ""),
                settings
                    .get(
                        ConfigConstants.ARMOR_AUTHENTICATION_LDAP_USERSEARCH,
                        "(sAMAccountName={0})")
                    .replace("{0}", authenticatedUser),
                SearchScope.SUBTREE);

        if (!result.next()) {
          throw new AuthException("No user '" + authenticatedUser + "' found");
        }

        entry = result.get();

        if (result.next()) {
          throw new AuthException("More than user found");
        }
      }

      dn = entry.getDn().toString();

      log.trace("User found with DN {}", dn);

      final Set<String> userRolesDn = new HashSet<String>();

      // Roles as an attribute of the user entry
      // Role names may also be held as the values of an attribute in the user's directory entry.
      // Use userRoleName to specify the name of this attribute.
      final String userRoleName =
          settings.get(
              ConfigConstants.ARMOR_AUTHENTICATION_AUTHORIZATION_LDAP_USERROLENAME, "memberOf");
      if (entry.get(userRoleName) != null) {
        final Value[] userRoles =
            Iterators.toArray(entry.get(userRoleName).iterator(), Value.class);

        for (int i = 0; i < userRoles.length; i++) {
          final Value value = userRoles[i];
          final String possibleRoleDN = value.getString();
          if (Dn.isValid(possibleRoleDN)) {
            userRolesDn.add(possibleRoleDN);
          }
        }

        log.trace("User roles count: {}", userRolesDn.size());
      }

      final Map<Tuple<String, Dn>, Entry> roles = new HashMap<Tuple<String, Dn>, Entry>();
      final String roleName =
          settings.get(ConfigConstants.ARMOR_AUTHENTICATION_AUTHORIZATION_LDAP_ROLENAME, "name");

      // replace {2}
      final String userRoleAttribute =
          settings.get(
              ConfigConstants.ARMOR_AUTHENTICATION_AUTHORIZATION_LDAP_USERROLEATTRIBUTE, null);
      String userRoleAttributeValue = null;

      if (userRoleAttribute != null) {
        userRoleAttributeValue =
            entry.get(userRoleAttribute) == null ? null : entry.get(userRoleAttribute).getString();
      }

      rolesResult =
          ldapConnection.search(
              settings.get(ConfigConstants.ARMOR_AUTHENTICATION_AUTHORIZATION_LDAP_ROLEBASE, ""),
              settings
                  .get(
                      ConfigConstants.ARMOR_AUTHENTICATION_AUTHORIZATION_LDAP_ROLESEARCH,
                      "(member={0})")
                  .replace("{0}", dn)
                  .replace("{1}", authenticatedUser)
                  .replace("{2}", userRoleAttributeValue == null ? "{2}" : userRoleAttributeValue),
              SearchScope.SUBTREE);

      for (final Iterator iterator = rolesResult.iterator(); iterator.hasNext(); ) {
        final Entry searchResultEntry = (Entry) iterator.next();
        roles.put(
            new Tuple<String, Dn>(searchResultEntry.getDn().toString(), searchResultEntry.getDn()),
            searchResultEntry);
      }

      log.trace("non user roles count: {}", roles.size());

      for (final Iterator<String> it = userRolesDn.iterator(); it.hasNext(); ) {
        final String stringVal = it.next();
        // lookup
        final Entry userRole = ldapConnection.lookup(stringVal);
        roles.put(new Tuple<String, Dn>(stringVal, null), userRole);
      }

      // nested roles
      if (settings.getAsBoolean(
          ConfigConstants.ARMOR_AUTHENTICATION_AUTHORIZATION_LDAP_RESOLVE_NESTED_ROLES, false)) {

        log.trace("Evaluate nested roles");

        final Set<Entry> nestedReturn = new HashSet<Entry>(roles.values());

        for (final Iterator<java.util.Map.Entry<Tuple<String, Dn>, Entry>> iterator =
                roles.entrySet().iterator();
            iterator.hasNext(); ) {
          final java.util.Map.Entry<Tuple<String, Dn>, Entry> _entry = iterator.next();

          final Set<Entry> x = resolveNestedRoles(_entry.getKey(), ldapConnection, roleName);

          log.trace("{}. nested roles for {} {}", x.size(), _entry.getKey(), roleName);

          nestedReturn.addAll(x);
        }

        for (final Iterator iterator = nestedReturn.iterator(); iterator.hasNext(); ) {
          final Entry entry2 = (Entry) iterator.next();
          final String role = entry2.get(roleName).getString();
          user.addRole(role);
        }

        if (user instanceof LdapUser) {
          ((LdapUser) user).addRoleEntries(nestedReturn);
        }

      } else {

        for (final Iterator iterator = roles.values().iterator(); iterator.hasNext(); ) {
          final Entry entry2 = (Entry) iterator.next();
          final String role = entry2.get(roleName).getString();
          user.addRole(role);
        }

        if (user instanceof LdapUser) {
          ((LdapUser) user).addRoleEntries(roles.values());
        }
      }

    } catch (final Exception e) {
      log.error(e.toString(), e);
      throw new AuthException(e);
    } finally {
      if (result != null) {
        result.close();
      }

      if (rolesResult != null) {
        rolesResult.close();
      }

      SecurityUtil.unbindAndCloseSilently(ldapConnection);
    }
  }