/* goodG2B() - use goodsource and badsink */
  public void goodG2B_sink(String data, HttpServletRequest request, HttpServletResponse response)
      throws Throwable {

    Hashtable<String, String> env = new Hashtable<String, String>();
    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    env.put(Context.PROVIDER_URL, "ldap://localhost:389");
    DirContext ctx = new InitialDirContext(env);

    String search =
        "(cn=" + data + ")"; /* POTENTIAL FLAW: unsanitized data from untrusted source */

    NamingEnumeration<SearchResult> answer = ctx.search("", search, null);
    while (answer.hasMore()) {
      SearchResult sr = answer.next();
      Attributes a = sr.getAttributes();
      NamingEnumeration<?> attrs = a.getAll();
      while (attrs.hasMore()) {
        Attribute attr = (Attribute) attrs.next();
        NamingEnumeration<?> values = attr.getAll();
        while (values.hasMore()) {
          response.getWriter().println(" Value: " + values.next().toString());
        }
      }
    }
  }
  /**
   * after a user has successfully logged in we want to build an access object for use in the
   * scheduling system
   *
   * @param String username
   * @param String group a group name to check for username in (via memberUid string)
   * @return boolean yes or no in the group
   * @throws NamingException when the search fails by DN this will be thrown
   */
  private boolean userInGroup(String username, String group) throws NamingException {
    // assume they are not
    boolean inGroup = false;

    // Specify the attributes to match
    Attributes matchAttrs = new BasicAttributes(true); // ignore attribute name case
    // set the common name for the group using defined prefix ie 'cn' or 'ou'
    matchAttrs.put(
        new BasicAttribute(
            this.GROUPS_LOC.substring(0, this.GROUPS_LOC.indexOf("=")),
            group)); // named group for access rights

    // Search for objects that have those matching attributes in the specified group location
    NamingEnumeration answer = ctx.search(this.GROUPS_LOC + this.BASE_DN, matchAttrs);

    // search for that user id in the member list
    while (answer.hasMore()) {
      SearchResult sr = (SearchResult) answer.next();
      if ((sr.getAttributes().get("memberuid").toString()).indexOf(username) >= 0) {
        // this user is in the specified group
        inGroup = true;
      }
    }
    System.err.println(username + " in " + group + ": " + new Boolean(inGroup).toString());
    return inGroup;
  }
  /* uses badsource and badsink - see how tools report flaws that don't always occur */
  public void bad(HttpServletRequest request, HttpServletResponse response) throws Throwable {
    String data;
    if (IO.static_returns_t_or_f()) {
      Logger log_bad = Logger.getLogger("local-logger");
      data = ""; /* init data */
      /* retrieve the property */
      Properties props = new Properties();
      FileInputStream finstr = null;
      try {
        finstr = new FileInputStream("../common/config.properties");
        props.load(finstr);
        data = props.getProperty("data");
      } catch (IOException ioe) {
        log_bad.warning("Error with stream reading");
      } finally {
        /* clean up stream reading objects */
        try {
          if (finstr != null) {
            finstr.close();
          }
        } catch (IOException ioe) {
          log_bad.warning("Error closing buffread");
        }
      }
    } else {

      java.util.logging.Logger log_good = java.util.logging.Logger.getLogger("local-logger");

      /* FIX: Use a hardcoded string */
      data = "foo";
    }

    Hashtable<String, String> env = new Hashtable<String, String>();
    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    env.put(Context.PROVIDER_URL, "ldap://localhost:389");
    DirContext ctx = new InitialDirContext(env);

    String search =
        "(cn=" + data + ")"; /* POTENTIAL FLAW: unsanitized data from untrusted source */

    NamingEnumeration<SearchResult> answer = ctx.search("", search, null);
    while (answer.hasMore()) {
      SearchResult sr = answer.next();
      Attributes a = sr.getAttributes();
      NamingEnumeration<?> attrs = a.getAll();
      while (attrs.hasMore()) {
        Attribute attr = (Attribute) attrs.next();
        NamingEnumeration<?> values = attr.getAll();
        while (values.hasMore()) {
          response.getWriter().println(" Value: " + values.next().toString());
        }
      }
    }
  }
  /* goodG2B1() - use goodsource and badsink by changing IO.staticTrue to IO.staticFalse */
  private void goodG2B1() throws Throwable {
    String data;
    if (IO.staticFalse) {
      /* INCIDENTAL: CWE 561 Dead Code, the code below will never run
       * but ensure data is inititialized before the Sink to avoid compiler errors */
      data = null;
    } else {

      /* FIX: Use a hardcoded string */
      data = "foo";
    }

    Hashtable<String, String> environmentHashTable = new Hashtable<String, String>();
    environmentHashTable.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    environmentHashTable.put(Context.PROVIDER_URL, "ldap://localhost:389");
    DirContext directoryContext = null;

    try {
      directoryContext = new InitialDirContext(environmentHashTable);
      /* POTENTIAL FLAW: data concatenated into LDAP search, which could result in LDAP Injection */
      String search = "(cn=" + data + ")";

      NamingEnumeration<SearchResult> answer = directoryContext.search("", search, null);
      while (answer.hasMore()) {
        SearchResult searchResult = answer.next();
        Attributes attributes = searchResult.getAttributes();
        NamingEnumeration<?> allAttributes = attributes.getAll();
        while (allAttributes.hasMore()) {
          Attribute attribute = (Attribute) allAttributes.next();
          NamingEnumeration<?> allValues = attribute.getAll();
          while (allValues.hasMore()) {
            IO.writeLine(" Value: " + allValues.next().toString());
          }
        }
      }
    } catch (NamingException exceptNaming) {
      IO.logger.log(Level.WARNING, "The LDAP service was not found or login failed.", exceptNaming);
    } finally {
      if (directoryContext != null) {
        try {
          directoryContext.close();
        } catch (NamingException exceptNaming) {
          IO.logger.log(Level.WARNING, "Error closing DirContext", exceptNaming);
        }
      }
    }
  }
  public void bad() throws Throwable {
    String data;

    badPrivate = true;
    data = bad_source();

    Hashtable<String, String> environmentHashTable = new Hashtable<String, String>();
    environmentHashTable.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    environmentHashTable.put(Context.PROVIDER_URL, "ldap://localhost:389");
    DirContext directoryContext = null;

    try {
      directoryContext = new InitialDirContext(environmentHashTable);
      /* POTENTIAL FLAW: data concatenated into LDAP search, which could result in LDAP Injection */
      String search = "(cn=" + data + ")";

      NamingEnumeration<SearchResult> answer = directoryContext.search("", search, null);
      while (answer.hasMore()) {
        SearchResult searchResult = answer.next();
        Attributes attributes = searchResult.getAttributes();
        NamingEnumeration<?> allAttributes = attributes.getAll();
        while (allAttributes.hasMore()) {
          Attribute attribute = (Attribute) allAttributes.next();
          NamingEnumeration<?> allValues = attribute.getAll();
          while (allValues.hasMore()) {
            IO.writeLine(" Value: " + allValues.next().toString());
          }
        }
      }
    } catch (NamingException exceptNaming) {
      IO.logger.log(Level.WARNING, "The LDAP service was not found or login failed.", exceptNaming);
    } finally {
      if (directoryContext != null) {
        try {
          directoryContext.close();
        } catch (NamingException exceptNaming) {
          IO.logger.log(Level.WARNING, "Error closing DirContext", exceptNaming);
        }
      }
    }
  }
  /* goodG2B() - use goodsource and badsink by changing the "if" so that
  both branches use the GoodSource */
  private void goodG2B(HttpServletRequest request, HttpServletResponse response) throws Throwable {
    String data;
    if (IO.static_returns_t_or_f()) {
      java.util.logging.Logger log_good = java.util.logging.Logger.getLogger("local-logger");
      /* FIX: Use a hardcoded string */
      data = "foo";
    } else {

      java.util.logging.Logger log_good = java.util.logging.Logger.getLogger("local-logger");

      /* FIX: Use a hardcoded string */
      data = "foo";
    }

    Hashtable<String, String> env = new Hashtable<String, String>();
    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    env.put(Context.PROVIDER_URL, "ldap://localhost:389");
    DirContext ctx = new InitialDirContext(env);

    String search =
        "(cn=" + data + ")"; /* POTENTIAL FLAW: unsanitized data from untrusted source */

    NamingEnumeration<SearchResult> answer = ctx.search("", search, null);
    while (answer.hasMore()) {
      SearchResult sr = answer.next();
      Attributes a = sr.getAttributes();
      NamingEnumeration<?> attrs = a.getAll();
      while (attrs.hasMore()) {
        Attribute attr = (Attribute) attrs.next();
        NamingEnumeration<?> values = attr.getAll();
        while (values.hasMore()) {
          response.getWriter().println(" Value: " + values.next().toString());
        }
      }
    }
  }
Example #7
0
  public Object getObjectInstance(
      Object obj, Name name, Context ctx, Hashtable<?, ?> env, Attributes inAttrs)
      throws Exception {

    if (obj instanceof DirContext) {
      Attribute objectClass = inAttrs.get("objectClass");
      NamingEnumeration<?> ne = objectClass.getAll();
      while (ne.hasMore()) {
        if (ne.next().equals("Service")) {
          return new Service(inAttrs);
        }
      }
    }

    return null;
  }
Example #8
0
 /**
  * Print Attributes to System.out
  *
  * @param attrs
  */
 private static void dump(Attributes attrs) {
   if (attrs == null) {
     System.out.println("No attributes");
   } else {
     /* Print each attribute */
     try {
       for (NamingEnumeration<? extends Attribute> ae = attrs.getAll(); ae.hasMore(); ) {
         Attribute attr = ae.next();
         System.out.println("attribute: " + attr.getID());
         /* print each value */
         for (NamingEnumeration<?> e = attr.getAll();
             e.hasMore();
             System.out.println("    value: " + e.next())) ;
       }
     } catch (NamingException e) {
       e.printStackTrace();
     }
   }
 } //	dump
 /** Exctract specified attributes from the ldapMatchingRule */
 Attributes extractAttributeIds(String[] attrIds) throws NamingException {
   Attributes attrs = new BasicAttributes();
   String val = null;
   for (int i = 0; i < attrIds.length; i++) {
     if (attrIds[i].equals(NUMERICOID)) {
       val = m_ldapMatchingRule.getID();
       if (val != null) {
         attrs.put(new BasicAttribute(NUMERICOID, val));
       }
     } else if (attrIds[i].equals(NAME)) {
       val = m_ldapMatchingRule.getName();
       if (val != null) {
         attrs.put(new BasicAttribute(NAME, val));
       }
     } else if (attrIds[i].equals(DESC)) {
       val = m_ldapMatchingRule.getDescription();
       if (val != null) {
         attrs.put(new BasicAttribute(DESC, val));
       }
     } else if (attrIds[i].equals(SYNTAX)) {
       val = m_ldapMatchingRule.getSyntaxString();
       if (val != null) {
         attrs.put(new BasicAttribute(SYNTAX, val));
       }
     } else if (attrIds[i].equals(APPLIES)) {
       String[] appliesToAttrs = m_ldapMatchingRule.getAttributes();
       if (appliesToAttrs != null && appliesToAttrs.length > 0) {
         BasicAttribute applies = new BasicAttribute(APPLIES);
         for (int a = 0; a < appliesToAttrs.length; a++) {
           applies.add(appliesToAttrs[a]);
         }
         attrs.put(applies);
       }
     } else if (attrIds[i].equals(OBSOLETE)) {
       if (m_ldapMatchingRule.getQualifier(OBSOLETE) != null) {
         attrs.put(new BasicAttribute(OBSOLETE, "true"));
       }
     } else {
       throw new NamingException(
           "Invalid schema attribute type for matching rule definition " + attrIds[i]);
     }
   }
   return attrs;
 }
  /** Parse Definition Attributes for a LDAP matching rule */
  static LDAPMatchingRuleSchema parseDefAttributes(Attributes attrs) throws NamingException {
    String name = null, oid = null, desc = null, syntax = null;
    boolean obsolete = false;
    Vector applies = new Vector();

    for (Enumeration attrEnum = attrs.getAll(); attrEnum.hasMoreElements(); ) {
      Attribute attr = (Attribute) attrEnum.nextElement();
      String attrName = attr.getID();
      if (attrName.equals(NAME)) {
        name = getSchemaAttrValue(attr);
      } else if (attrName.equals(NUMERICOID)) {
        oid = getSchemaAttrValue(attr);
      } else if (attrName.equals(SYNTAX)) {
        syntax = getSchemaAttrValue(attr);
      } else if (attrName.equals(DESC)) {
        desc = getSchemaAttrValue(attr);
      } else if (attrName.equals(APPLIES)) {
        for (Enumeration valEnum = attr.getAll(); valEnum.hasMoreElements(); ) {
          applies.addElement((String) valEnum.nextElement());
        }
      } else if (attrName.equals(OBSOLETE)) {
        obsolete = parseTrueFalseValue(attr);
      } else {
        throw new NamingException(
            "Invalid schema attribute type for matching rule definition " + attrName);
      }
    }

    LDAPMatchingRuleSchema mrule =
        new LDAPMatchingRuleSchema(name, oid, desc, vectorToStringAry(applies), syntax);

    if (obsolete) {
      mrule.setQualifier(OBSOLETE, "");
    }
    return mrule;
  }
  /* uses badsource and badsink */
  public void bad() throws Throwable {
    String data;
    if (IO.staticTrue) {
      data = ""; /* Initialize data */
      /* Read data using a listening tcp connection */
      {
        ServerSocket listener = null;
        Socket socket = null;
        BufferedReader readerBuffered = null;
        InputStreamReader readerInputStream = null;
        /* Read data using a listening tcp connection */
        try {
          listener = new ServerSocket(39543);
          socket = listener.accept();
          /* read input from socket */
          readerInputStream = new InputStreamReader(socket.getInputStream(), "UTF-8");
          readerBuffered = new BufferedReader(readerInputStream);
          /* POTENTIAL FLAW: Read data using a listening tcp connection */
          data = readerBuffered.readLine();
        } catch (IOException exceptIO) {
          IO.logger.log(Level.WARNING, "Error with stream reading", exceptIO);
        } finally {
          /* Close stream reading objects */
          try {
            if (readerBuffered != null) {
              readerBuffered.close();
            }
          } catch (IOException exceptIO) {
            IO.logger.log(Level.WARNING, "Error closing BufferedReader", exceptIO);
          }

          try {
            if (readerInputStream != null) {
              readerInputStream.close();
            }
          } catch (IOException exceptIO) {
            IO.logger.log(Level.WARNING, "Error closing InputStreamReader", exceptIO);
          }

          /* Close socket objects */
          try {
            if (socket != null) {
              socket.close();
            }
          } catch (IOException exceptIO) {
            IO.logger.log(Level.WARNING, "Error closing Socket", exceptIO);
          }

          try {
            if (listener != null) {
              listener.close();
            }
          } catch (IOException exceptIO) {
            IO.logger.log(Level.WARNING, "Error closing ServerSocket", exceptIO);
          }
        }
      }
    } else {
      /* INCIDENTAL: CWE 561 Dead Code, the code below will never run
       * but ensure data is inititialized before the Sink to avoid compiler errors */
      data = null;
    }

    Hashtable<String, String> environmentHashTable = new Hashtable<String, String>();
    environmentHashTable.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    environmentHashTable.put(Context.PROVIDER_URL, "ldap://localhost:389");
    DirContext directoryContext = null;

    try {
      directoryContext = new InitialDirContext(environmentHashTable);
      /* POTENTIAL FLAW: data concatenated into LDAP search, which could result in LDAP Injection */
      String search = "(cn=" + data + ")";

      NamingEnumeration<SearchResult> answer = directoryContext.search("", search, null);
      while (answer.hasMore()) {
        SearchResult searchResult = answer.next();
        Attributes attributes = searchResult.getAttributes();
        NamingEnumeration<?> allAttributes = attributes.getAll();
        while (allAttributes.hasMore()) {
          Attribute attribute = (Attribute) allAttributes.next();
          NamingEnumeration<?> allValues = attribute.getAll();
          while (allValues.hasMore()) {
            IO.writeLine(" Value: " + allValues.next().toString());
          }
        }
      }
    } catch (NamingException exceptNaming) {
      IO.logger.log(Level.WARNING, "The LDAP service was not found or login failed.", exceptNaming);
    } finally {
      if (directoryContext != null) {
        try {
          directoryContext.close();
        } catch (NamingException exceptNaming) {
          IO.logger.log(Level.WARNING, "Error closing DirContext", exceptNaming);
        }
      }
    }
  }
  /**
   * Returns a pair consisting of a MarshalledObject and attributes to be bound with the stub.
   *
   * @param obj The non-null object to store.
   * @param inAttrs The possible null attributes to store with object.
   * @return A non-null Result consisting of the MarshalledObject and attributes.
   */
  private static DirStateFactory.Result jrmpObject(Object obj, Attributes inAttrs)
      throws NamingException {
    try {
      Object mobj = new MarshalledObject(obj);

      Attributes outAttrs = null;
      Attribute cname = null;
      Attribute tnames = null;
      Attribute objectClass = null;

      if (inAttrs != null) {
        // Get existing objectclass attribute
        objectClass = (Attribute) inAttrs.get("objectClass");
        if (objectClass == null && !inAttrs.isCaseIgnored()) {
          // %%% workaround
          objectClass = (Attribute) inAttrs.get("objectclass");
        }

        // No objectclasses supplied, use "top" to start
        if (objectClass == null) {
          objectClass = new BasicAttribute("objectClass", "top");
        } else {
          objectClass = (Attribute) objectClass.clone();
        }

        cname = inAttrs.get(CLASSNAME_ATTRID);
        tnames = inAttrs.get(CLASSNAMES_ATTRID);

        outAttrs = (Attributes) inAttrs.clone();
      } else {
        outAttrs = new BasicAttributes(true);
        objectClass = new BasicAttribute("objectClass", "top");
      }

      if (cname == null) {
        outAttrs.put(CLASSNAME_ATTRID, obj.getClass().getName());
      }
      if (tnames == null) {
        Attribute tAttr = LdapCtxFactory.createTypeNameAttr(obj.getClass());
        if (tAttr != null) {
          outAttrs.put(tAttr);
        }
      }

      boolean structural =
          (objectClass.size() == 0 || (objectClass.size() == 1 && objectClass.contains("top")));

      if (structural) {
        objectClass.add(STRUCTURAL_OCID);
      }
      objectClass.add(MARSHALLED_OCID);
      outAttrs.put(objectClass);

      return new DirStateFactory.Result(mobj, outAttrs);

    } catch (java.io.IOException e) {
      NamingException ne = new NamingException("Cannot create MarshallObject for " + obj);
      ne.setRootCause(e);
      throw ne;
    }
  }
  protected NameClassPair createItem(String dn, Attributes attrs, Vector respCtls)
      throws NamingException {

    Object obj = null;

    String relStart; // name relative to starting search context
    String relHome; // name relative to homeCtx.currentDN
    boolean relative = true; // whether relative to currentDN

    // need to strip off all but lowest component of dn
    // so that is relative to current context (currentDN)

    try {
      Name parsed = new LdapName(dn);
      // System.err.println("dn string: " + dn);
      // System.err.println("dn name: " + parsed);

      if (startName != null && parsed.startsWith(startName)) {
        relStart = parsed.getSuffix(startName.size()).toString();
        relHome = parsed.getSuffix(homeCtx.currentParsedDN.size()).toString();
      } else {
        relative = false;
        relHome =
            relStart =
                LdapURL.toUrlString(
                    homeCtx.hostname, homeCtx.port_number, dn, homeCtx.hasLdapsScheme);
      }
    } catch (NamingException e) {
      // could not parse name
      relative = false;
      relHome =
          relStart =
              LdapURL.toUrlString(
                  homeCtx.hostname, homeCtx.port_number, dn, homeCtx.hasLdapsScheme);
    }

    // Name relative to search context
    CompositeName cn = new CompositeName();
    if (!relStart.equals("")) {
      cn.add(relStart);
    }

    // Name relative to homeCtx
    CompositeName rcn = new CompositeName();
    if (!relHome.equals("")) {
      rcn.add(relHome);
    }
    // System.err.println("relStart: " + cn);
    // System.err.println("relHome: " + rcn);

    // Fix attributes to be able to get schema
    homeCtx.setParents(attrs, rcn);

    // only generate object when requested
    if (searchArgs.cons.getReturningObjFlag()) {

      if (attrs.get(Obj.JAVA_ATTRIBUTES[Obj.CLASSNAME]) != null) {
        // Entry contains Java-object attributes (ser/ref object)
        // serialized object or object reference
        obj = Obj.decodeObject(attrs);
      }
      if (obj == null) {
        obj = new LdapCtx(homeCtx, dn);
      }

      // Call getObjectInstance before removing unrequested attributes
      try {
        // rcn is either relative to homeCtx or a fully qualified DN
        obj =
            DirectoryManager.getObjectInstance(
                obj, rcn, (relative ? homeCtx : null), homeCtx.envprops, attrs);
      } catch (NamingException e) {
        throw e;
      } catch (Exception e) {
        NamingException ne = new NamingException("problem generating object using object factory");
        ne.setRootCause(e);
        throw ne;
      }

      // remove Java attributes from result, if necessary
      // Even if CLASSNAME attr not there, there might be some
      // residual attributes

      String[] reqAttrs;
      if ((reqAttrs = searchArgs.reqAttrs) != null) {
        // create an attribute set for those requested
        Attributes rattrs = new BasicAttributes(true); // caseignore
        for (int i = 0; i < reqAttrs.length; i++) {
          rattrs.put(reqAttrs[i], null);
        }
        for (int i = 0; i < Obj.JAVA_ATTRIBUTES.length; i++) {
          // Remove Java-object attributes if not requested
          if (rattrs.get(Obj.JAVA_ATTRIBUTES[i]) == null) {
            attrs.remove(Obj.JAVA_ATTRIBUTES[i]);
          }
        }
      }
    }

    /*
     * name in search result is either the stringified composite name
     * relative to the search context that can be passed directly to
     * methods of the search context, or the fully qualified DN
     * which can be used with the initial context.
     */
    SearchResult sr;
    if (respCtls != null) {
      sr =
          new SearchResultWithControls(
              (relative ? cn.toString() : relStart),
              obj,
              attrs,
              relative,
              homeCtx.convertControls(respCtls));
    } else {
      sr = new SearchResult((relative ? cn.toString() : relStart), obj, attrs, relative);
    }
    sr.setNameInNamespace(dn);
    return sr;
  }
  /**
   * This method will test if a user has access to the LDAP, if so it will then check the list of
   * groups and check for is access
   *
   * @param String username as named via a uid in the LDAP
   * @param String password clear text in LDAP
   * @return Hashtable authenticate object
   */
  public Hashtable authenticate(String username, String password, String keyfob_id) {

    Hashtable authHT = new Hashtable();

    if (keyfob_id != null) {
      System.out.println("attempted keyfob value: " + keyfob_id);
      // we need to bind with our anon bind user
      username = this.AD_ANON_BIND_UNAME;
      password = this.AD_ANON_BIND_PWORD;
    }

    // assume they will not pass the test
    boolean authenticated = false;

    // first check to see if we even need to hit LDAP (not overridden)
    if (this.LDAP_OVERRIDE) {
      System.out.println("Override Authentication");
      // just check against stored username/password, put in all groups
      if (username.equals(this.LDAP_OVERRIDE_UNAME) && password.equals(this.LDAP_OVERRIDE_PWORD)) {
        authenticated = true;
        // just add then to each group
        for (String key : groups.keySet()) {
          // push the name of the group and access to it boolean
          authHT.put(key, true); // method throws NamingException
        }
      }

    } else {
      // authenticate agianst creditials server
      System.err.println("Trying " + this.PROVIDER_TYPE + " authentication by: " + username);

      try {

        // build a hash table to pass as a bindable event
        // Set up environment for creating initial context
        Hashtable<String, String> env = new Hashtable<String, String>();

        env.put(Context.INITIAL_CONTEXT_FACTORY, this.INITIAL_CONTEXT_FACTORY);

        env.put(Context.SECURITY_AUTHENTICATION, this.SECURITY_AUTHENTICATION);
        // we take the uid to authenticate, pair it with the username, and append the base location
        env.put(Context.PROVIDER_URL, this.PROVIDER_URL);

        if (this.PROVIDER_TYPE.equals("AD")) {
          env.put(Context.SECURITY_PRINCIPAL, username + "@" + this.AD_DOMAIN);
        } else if (this.PROVIDER_TYPE.equals("LDAP")) {
          env.put(
              Context.SECURITY_PRINCIPAL, "uid=" + username + "," + this.USERS_LOC + this.BASE_DN);
        } // we don't need to throw errors here because first try/catch finds it

        env.put(Context.SECURITY_CREDENTIALS, password);

        // send env assigments to console
        // enumerateContents(env.elements());

        /** now that we have our hash values lets go authenticate */

        // first we want to connect to the LDAP Server and create initial context
        // making sure the user name and password are valid
        ctx =
            new InitialDirContext(
                env); // Throws AuthenticationException if not valid username/password
        // WE NEVER GO PAST HERE IF AuthenticationException THROWN
        System.err.println("connection and creditials valid");

        /**
         * we just split the two paths of AD and LDAP authentication because the LDAP way worked and
         * we are migrating to AD. However we want to be able to easily switch back until the LDAP
         * service is discontinued. Theoretically both services should be 'searchable' the same way
         * at some point the LDAP code should be removed or universal code written
         */
        if (this.PROVIDER_TYPE.equals("AD")) {
          /** AD way, get the group list, if they match add */
          SearchControls constraints = new SearchControls();
          constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);

          // either search by user name or by keyfob id. either way will return a user if one is
          // found
          NamingEnumeration results = null;
          if (keyfob_id != null) {
            // we don't challenge on keyfob. assumed if you have keyfob you are that user
            System.out.println("searching for keyfob id: >" + keyfob_id + "<");
            results =
                ctx.search(
                    this.USERS_LOC + this.BASE_DN,
                    "(" + this.ATTRIBUTE_NAME_KEYFOB_ID + "=" + keyfob_id + ")",
                    constraints);
            authHT.put("keyfob_id", keyfob_id); // pass it back as proof positive we found it
          } else {
            results =
                ctx.search(
                    this.USERS_LOC + this.BASE_DN,
                    "(" + this.ATTRIBUTE_NAME_UNAME + "=" + username + ")",
                    constraints);
          }

          while (results != null && results.hasMore()) {
            SearchResult sr = (SearchResult) results.next();
            String dn = sr.getName() + ", " + this.USERS_LOC + this.BASE_DN;

            Attributes ar = ctx.getAttributes(dn, MY_ATTRS);
            if (ar == null) {
              // we need the user to have attributes
              throw new Exception("Entry " + dn + " has none of the specified attributes\n");
            }
            for (int i = 0; i < MY_ATTRS.length; i++) {
              Attribute attr = ar.get(MY_ATTRS[i]);
              if (attr == null) {
                continue;
              }
              System.out.println(MY_ATTRS[i] + ":");
              for (Enumeration vals = attr.getAll(); vals.hasMoreElements(); ) {
                String temp_next_element = vals.nextElement().toString(); // returns generic Object
                System.out.println("\t" + temp_next_element);

                // push the attributes to the auth HT
                if (!(authHT.containsKey(MY_ATTRS[i]))) {
                  // push the name of the group and access to it boolean
                  authHT.put(MY_ATTRS[i], temp_next_element);
                }

                // see if this element value matches any of my groups
                for (String key : groups.keySet()) {
                  if (temp_next_element
                      .toLowerCase()
                      .startsWith("cn=" + groups.get(key).toLowerCase())) {
                    // push the name of the group and access to it boolean
                    authHT.put(key, true);

                    // if user is found in ANY of the predefined groups they are 'authenticated' to
                    // login.
                    // RolemManager.as handles ACL
                    authenticated = true;
                  }
                }
              }
            }
          }

          // now for any groups not found, set them to false
          for (String key : groups.keySet()) {
            if (!(authHT.containsKey(key))) {
              // push the name of the group and access to it boolean
              authHT.put(key, false);
            }
          }

          // end AD WAY

        } else if (this.PROVIDER_TYPE.equals("LDAP")) {
          // authenticated only in the sense they are a valid AD user
          authenticated = true;

          // now that we have verified they are a valid user, lets see what type of access they have
          // groups are specified in the config file as "GROUP_<name>" key=value pairs where value
          // is the LDAP group name
          // and key is what we are looking for in the scheduling app
          for (String key : groups.keySet()) {
            // push the name of the group and access to it boolean
            authHT.put(
                key,
                new Boolean(
                    userInGroup(username, groups.get(key)))); // method throws NamingException
          }
        } else {
          throw new Exception("Provider type not found.");
        }

        // Close the context when we're done
        ctx.close();
      } catch (AuthenticationException e) {
        // binding to LDAP server with provided username/password failed
        // e.printStackTrace();
        System.err.println(
            "AuthenticationException: "
                + e.getMessage()); // outputs -> [LDAP: error code 49 - Invalid Credentials]
        errorStack += e.getMessage() + "\n";
      } catch (NamingException e) {
        // catches invalid DN. Should not be thrown unless changes made to DN
        // Could also fail from the context of the called method userInGroup
        System.err.println("NamingException: " + e.getMessage());
        // e.printStackTrace();
        errorStack += e.getMessage() + "\n";
      } catch (Exception e) {
        e.printStackTrace();
        System.err.println("Exception: " + e.getMessage());
        errorStack += e.getMessage() + "\n";
      } finally { // make sure our connection is closed if relevant
        if (ctx != null) {
          try {
            ctx.close();
          } catch (NamingException e) {
            throw new RuntimeException(e);
          }
        }
      }
    }

    // push whether or not it was authenticated
    authHT.put("authenticated", new Boolean(authenticated));

    // spill contents to catalina.out file
    enumerateContents(authHT.keys());
    enumerateContents(authHT.elements());

    return (authHT);
  }