@Override
    public LdapEntry[] groupSearch(DirContext dirContext, LdapEntry entry)
        throws IOException, NamingException {
      Set<LdapEntry> foundEntries = new HashSet<LdapEntry>();
      // Load the list of group.
      Attributes groups =
          dirContext.getAttributes(entry.getDistinguishedName(), new String[] {groupAttribute});
      Attribute groupRef = groups.get(groupAttribute);
      if (groupRef != null && groupRef.size() > 0) {
        NamingEnumeration<String> groupRefValues = (NamingEnumeration<String>) groupRef.getAll();
        while (groupRefValues.hasMore()) {
          String distingushedName = groupRefValues.next();
          SECURITY_LOGGER.tracef("Group found with distinguishedName=%s", distingushedName);
          String simpleName = null;
          if (groupNameAttribute != null) {
            // Load the Name
            Attributes groupNameAttrs =
                dirContext.getAttributes(distingushedName, new String[] {groupNameAttribute});
            Attribute groupNameAttr = groupNameAttrs.get(groupNameAttribute);
            simpleName = (String) groupNameAttr.get();
            SECURITY_LOGGER.tracef(
                "simpleName %s loaded for group with distinguishedName=%s",
                simpleName, distingushedName);
          } else {
            SECURITY_LOGGER.trace("No groupNameAttribute to load simpleName");
          }
          foundEntries.add(new LdapEntry(simpleName, distingushedName));
        }
      } else {
        SECURITY_LOGGER.tracef("No groups found for %s", entry);
      }

      return foundEntries.toArray(new LdapEntry[foundEntries.size()]);
    }
  /**
   * Infer the root DN.
   *
   * @return null if not found.
   */
  private String inferRootDN(String server) {
    try {
      Hashtable<String, String> props = new Hashtable<String, String>();
      if (managerDN != null) {
        props.put(Context.SECURITY_PRINCIPAL, managerDN);
        props.put(Context.SECURITY_CREDENTIALS, getManagerPassword());
      }
      props.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
      props.put(Context.PROVIDER_URL, toProviderUrl(fixNull(getServerUrl()), ""));

      DirContext ctx = new InitialDirContext(props);
      Attributes atts = ctx.getAttributes("");
      Attribute a = atts.get("defaultNamingContext");
      if (a != null
          && a.get()
              != null) { // this entry is available on Active Directory. See
                         // http://msdn2.microsoft.com/en-us/library/ms684291(VS.85).aspx
        return a.get().toString();
      }

      a = atts.get("namingcontexts");
      if (a == null) {
        LOGGER.warning("namingcontexts attribute not found in root DSE of " + server);
        return null;
      }
      return a.get().toString();
    } catch (NamingException e) {
      LOGGER.log(Level.WARNING, "Failed to connect to LDAP to infer Root DN for " + server, e);
      return null;
    }
  }
Beispiel #3
0
  /**
   * Returns the host name and port that the specified XMPP server can be reached at for
   * client-to-server communication. A DNS lookup for a SRV record in the form
   * "_xmpp-client._tcp.example.com" is attempted, according to section 14.4 of RFC 3920. If that
   * lookup fails, a lookup in the older form of "_jabber._tcp.example.com" is attempted since
   * servers that implement an older version of the protocol may be listed using that notation. If
   * that lookup fails as well, it's assumed that the XMPP server lives at the host resolved by a
   * DNS lookup at the specified domain on the default port of 5222.
   *
   * <p>As an example, a lookup for "example.com" may return "im.example.com:5269".
   *
   * <p>Note on SRV record selection. We now check priority and weight, but we still don't do this
   * correctly. The missing behavior is this: if we fail to reach a host based on its SRV record
   * then we need to select another host from the other SRV records. In Smack 3.1.1 we're not going
   * to be able to do the major system redesign to correct this.
   *
   * @param domain the domain.
   * @return a HostAddress, which encompasses the hostname and port that the XMPP server can be
   *     reached at for the specified domain.
   */
  public static HostAddress resolveXMPPDomain(String domain) {
    if (context == null) {
      return new HostAddress(domain, 5222);
    }
    String key = "c" + domain;
    // Return item from cache if it exists.
    if (cache.containsKey(key)) {
      HostAddress address = (HostAddress) cache.get(key);
      if (address != null) {
        return address;
      }
    }
    String bestHost = domain;
    int bestPort = 5222;
    int bestPriority = 0;
    int bestWeight = 0;
    try {
      Attributes dnsLookup =
          context.getAttributes("_xmpp-client._tcp." + domain, new String[] {"SRV"});
      Attribute srvAttribute = dnsLookup.get("SRV");
      NamingEnumeration srvRecords = srvAttribute.getAll();
      while (srvRecords.hasMore()) {
        String srvRecord = (String) srvRecords.next();
        String[] srvRecordEntries = srvRecord.split(" ");
        int priority = Integer.parseInt(srvRecordEntries[srvRecordEntries.length - 4]);
        int port = Integer.parseInt(srvRecordEntries[srvRecordEntries.length - 2]);
        int weight = Integer.parseInt(srvRecordEntries[srvRecordEntries.length - 3]);
        String host = srvRecordEntries[srvRecordEntries.length - 1];

        // Randomize the weight.
        weight *= Math.random() * weight;

        if ((bestPriority == 0) || (priority < bestPriority)) {
          // Choose a server with the lowest priority.
          bestPriority = priority;
          bestWeight = weight;
          bestHost = host;
          bestPort = port;
        } else if (priority == bestPriority) {
          // When we have like priorities then randomly choose a server based on its weight
          // The weights were randomized above.
          if (weight > bestWeight) {
            bestWeight = weight;
            bestHost = host;
            bestPort = port;
          }
        }
      }
    } catch (Exception e) {
      // Ignore.
    }
    // Host entries in DNS should end with a ".".
    if (bestHost.endsWith(".")) {
      bestHost = bestHost.substring(0, bestHost.length() - 1);
    }
    HostAddress address = new HostAddress(bestHost, bestPort);
    // Add item to cache.
    cache.put(key, address);
    return address;
  }
Beispiel #4
0
  public UserDTO doLdapAuthentication(UserDTO dto) throws Exception {
    log.info("INSIDE LDAP AUTHENTICATION 2");
    UserDTO ldapDTO = null;
    String url = "ldap://172.18.20.0:10389";
    Hashtable<String, String> env = new Hashtable<String, String>();
    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    env.put(Context.PROVIDER_URL, url);
    env.put(Context.SECURITY_AUTHENTICATION, "simple");
    env.put(Context.SECURITY_PRINCIPAL, "uid=admin,ou=system");
    env.put(Context.SECURITY_CREDENTIALS, "secret");

    try {
      ldapDTO = new UserDTO();
      DirContext ctx = new InitialDirContext(env);
      Attributes attrs = ctx.getAttributes("cn=" + dto.getUsername() + ",ou=users,ou=system");
      Attribute userPassword = attrs.get("userPassword");
      String ldapPasswordFromDB = new String((byte[]) userPassword.get());
      String md5EncryptedPassword = encryptLdapPassword("md5", dto.getPassword());
      if (md5EncryptedPassword.equalsIgnoreCase(ldapPasswordFromDB)) {
        ldapDTO.setEmployeeId((String) (attrs.get("employeeNumber").get()));
        ldapDTO.setEmployeeType((String) (attrs.get("employeeType").get()));
        ldapDTO.setUsername((String) (attrs.get("cn").get()));
      }
      ctx.close();

    } catch (Exception e) {
      e.printStackTrace();
    }
    return ldapDTO;
  }
  /**
   * Connect to the DirContext, and retrieve the bound object, as well as its attributes. If no
   * object is bound with the name specified in the URL, then an IOException is thrown.
   *
   * @throws IOException Object not found
   */
  @Override
  public void connect() throws IOException {

    if (!connected) {

      try {
        date = System.currentTimeMillis();
        String path = URL_DECODER.convert(getURL().getFile(), false);
        if (context instanceof ProxyDirContext) {
          ProxyDirContext proxyDirContext = (ProxyDirContext) context;
          String hostName = proxyDirContext.getHostName();
          String contextPath = proxyDirContext.getContextPath();
          if (hostName != null) {
            if (!path.startsWith("/" + hostName + "/")) return;
            path = path.substring(hostName.length() + 1);
          }
          if (contextPath != null) {
            if (!path.startsWith(contextPath + "/")) {
              return;
            }
            path = path.substring(contextPath.length());
          }
        }
        object = context.lookup(path);
        attributes = context.getAttributes(path);
        if (object instanceof Resource) resource = (Resource) object;
        if (object instanceof DirContext) collection = (DirContext) object;
      } catch (NamingException e) {
        // Object not found
      }

      connected = true;
    }
  }
    public FormValidation doServerCheck(
        @QueryParameter final String server,
        @QueryParameter final String managerDN,
        @QueryParameter final String managerPassword) {

      if (!Jenkins.getInstance().hasPermission(Jenkins.ADMINISTER)) return FormValidation.ok();

      try {
        Hashtable<String, String> props = new Hashtable<String, String>();
        if (managerDN != null && managerDN.trim().length() > 0 && !"undefined".equals(managerDN)) {
          props.put(Context.SECURITY_PRINCIPAL, managerDN);
        }
        if (managerPassword != null
            && managerPassword.trim().length() > 0
            && !"undefined".equals(managerPassword)) {
          props.put(Context.SECURITY_CREDENTIALS, managerPassword);
        }

        props.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        props.put(Context.PROVIDER_URL, toProviderUrl(server, ""));

        DirContext ctx = new InitialDirContext(props);
        ctx.getAttributes("");
        return FormValidation.ok(); // connected
      } catch (NamingException e) {
        // trouble-shoot
        Matcher m =
            Pattern.compile(
                    "(ldaps?://)?([^:]+)(?:\\:(\\d+))?(\\s+(ldaps?://)?([^:]+)(?:\\:(\\d+))?)*")
                .matcher(server.trim());
        if (!m.matches())
          return FormValidation.error(
              hudson.security.Messages.LDAPSecurityRealm_SyntaxOfServerField());

        try {
          InetAddress adrs = InetAddress.getByName(m.group(2));
          int port = m.group(1) != null ? 636 : 389;
          if (m.group(3) != null) port = Integer.parseInt(m.group(3));
          Socket s = new Socket(adrs, port);
          s.close();
        } catch (UnknownHostException x) {
          return FormValidation.error(
              hudson.security.Messages.LDAPSecurityRealm_UnknownHost(x.getMessage()));
        } catch (IOException x) {
          return FormValidation.error(
              x,
              hudson.security.Messages.LDAPSecurityRealm_UnableToConnect(server, x.getMessage()));
        }

        // otherwise we don't know what caused it, so fall back to the general error report
        // getMessage() alone doesn't offer enough
        return FormValidation.error(
            e, hudson.security.Messages.LDAPSecurityRealm_UnableToConnect(server, e));
      } catch (NumberFormatException x) {
        // The getLdapCtxInstance method throws this if it fails to parse the port number
        return FormValidation.error(hudson.security.Messages.LDAPSecurityRealm_InvalidPortNumber());
      }
    }
 public Attributes getAttributes(String name, String[] attrIds) throws NamingException {
   ResolveResult res = getRootURLContext(name, myEnv);
   DirContext ctx = (DirContext) res.getResolvedObj();
   try {
     return ctx.getAttributes(res.getRemainingName(), attrIds);
   } finally {
     ctx.close();
   }
 }
  /**
   * @see net.jforum.sso.LoginAuthenticator#validateLogin(java.lang.String, java.lang.String,
   *     java.util.Map)
   */
  public User validateLogin(String username, String password, Map extraParams) {
    Hashtable environment = this.prepareEnvironment();

    StringBuffer principal =
        new StringBuffer(256)
            .append(SystemGlobals.getValue(ConfigKeys.LDAP_LOGIN_PREFIX))
            .append(username)
            .append(',')
            .append(SystemGlobals.getValue(ConfigKeys.LDAP_LOGIN_SUFFIX));

    environment.put(Context.SECURITY_PRINCIPAL, principal.toString());
    environment.put(Context.SECURITY_CREDENTIALS, password);

    DirContext dir = null;

    try {
      dir = new InitialDirContext(environment);

      String lookupPrefix = SystemGlobals.getValue(ConfigKeys.LDAP_LOOKUP_PREFIX);
      String lookupSuffix = SystemGlobals.getValue(ConfigKeys.LDAP_LOOKUP_SUFFIX);

      if (lookupPrefix == null || lookupPrefix.length() == 0) {
        lookupPrefix = SystemGlobals.getValue(ConfigKeys.LDAP_LOGIN_PREFIX);
      }

      if (lookupSuffix == null || lookupSuffix.length() == 0) {
        lookupSuffix = SystemGlobals.getValue(ConfigKeys.LDAP_LOGIN_SUFFIX);
      }

      String lookupPrincipal = lookupPrefix + username + "," + lookupSuffix;

      Attribute att =
          dir.getAttributes(lookupPrincipal)
              .get(SystemGlobals.getValue(ConfigKeys.LDAP_FIELD_EMAIL));

      SSOUtils utils = new SSOUtils();

      if (!utils.userExists(username)) {
        String email = att != null ? (String) att.get() : "noemail";
        utils.register("ldap", email);
      }

      return utils.getUser();
    } catch (AuthenticationException e) {
      return null;
    } catch (NamingException e) {
      return null;
    } finally {
      if (dir != null) {
        try {
          dir.close();
        } catch (NamingException e) {
          // close jndi context
        }
      }
    }
  }
Beispiel #9
0
  public static String doLookup(String hostName) throws NamingException {

    int pos = hostName.indexOf('@');
    String domain = hostName.substring(++pos);

    Hashtable<String, String> env = new Hashtable<String, String>();
    env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
    DirContext ictx = new InitialDirContext(env);
    Attributes attrs = ictx.getAttributes(domain, new String[] {"MX"});
    Attribute attr = attrs.get("MX");

    if ((attr == null) || (attr.size() == 0)) {
      attrs = ictx.getAttributes(domain, new String[] {"A"});
      attr = attrs.get("A");
    }
    if (attr == null) return "no server found";
    return (String) (attr.get());
  }
Beispiel #10
0
 /**
  * Returns the host name and port that the specified XMPP server can be reached at for
  * server-to-server communication. A DNS lookup for a SRV record in the form
  * "_xmpp-server._tcp.example.com" is attempted, according to section 14.4 of RFC 3920. If that
  * lookup fails, a lookup in the older form of "_jabber._tcp.example.com" is attempted since
  * servers that implement an older version of the protocol may be listed using that notation. If
  * that lookup fails as well, it's assumed that the XMPP server lives at the host resolved by a
  * DNS lookup at the specified domain on the default port of 5269.
  *
  * <p>As an example, a lookup for "example.com" may return "im.example.com:5269".
  *
  * @param domain the domain.
  * @return a HostAddress, which encompasses the hostname and port that the XMPP server can be
  *     reached at for the specified domain.
  */
 public static HostAddress resolveXMPPServerDomain(String domain) {
   if (context == null) {
     return new HostAddress(domain, 5269);
   }
   String key = "s" + domain;
   // Return item from cache if it exists.
   if (cache.containsKey(key)) {
     HostAddress address = (HostAddress) cache.get(key);
     if (address != null) {
       return address;
     }
   }
   String host = domain;
   int port = 5269;
   try {
     Attributes dnsLookup =
         context.getAttributes("_xmpp-server._tcp." + domain, new String[] {"SRV"});
     String srvRecord = (String) dnsLookup.get("SRV").get();
     String[] srvRecordEntries = srvRecord.split(" ");
     port = Integer.parseInt(srvRecordEntries[srvRecordEntries.length - 2]);
     host = srvRecordEntries[srvRecordEntries.length - 1];
   } catch (Exception e) {
     // Attempt lookup with older "jabber" name.
     try {
       Attributes dnsLookup =
           context.getAttributes("_jabber._tcp." + domain, new String[] {"SRV"});
       String srvRecord = (String) dnsLookup.get("SRV").get();
       String[] srvRecordEntries = srvRecord.split(" ");
       port = Integer.parseInt(srvRecordEntries[srvRecordEntries.length - 2]);
       host = srvRecordEntries[srvRecordEntries.length - 1];
     } catch (Exception e2) {
       // Ignore.
     }
   }
   // Host entries in DNS should end with a ".".
   if (host.endsWith(".")) {
     host = host.substring(0, host.length() - 1);
   }
   HostAddress address = new HostAddress(host, port);
   // Add item to cache.
   cache.put(key, address);
   return address;
 }
Beispiel #11
0
  static LdapType guessType(final DirContext ctx) throws NamingException {
    final Attributes rootAtts = ctx.getAttributes("");
    Attribute supported = rootAtts.get("supportedCapabilities");
    if (supported != null
        && (supported.contains("1.2.840.113556.1.4.800")
            || supported.contains("1.2.840.113556.1.4.1851"))) {
      return new ActiveDirectory();
    }

    return RFC_2307;
  }
 public Attributes getAttributes(Name name, String[] attrIds) throws NamingException {
   if (name.size() == 1) {
     return getAttributes(name.get(0), attrIds);
   } else {
     DirContext ctx = getContinuationDirContext(name);
     try {
       return ctx.getAttributes(name.getSuffix(1), attrIds);
     } finally {
       ctx.close();
     }
   }
 }
  /**
   * Gets values of an entry attribute using a Distinguished Name and the name of the attribute
   *
   * @param DN Distinguished Name of the entry
   * @param attribute name of the attribute
   * @return List<Object>
   * @exception LDAPException
   */
  public List<Object> getEntryAttribute(final String DN, final String attribute)
      throws LDAPException {
    List<Object> _values = new ArrayList<Object>();
    try {
      DirContext ctx = connection.connect();
      if (ctx == null) {
        throw new LDAPException("directory service not available");
      }
      Attributes _atts = null;
      if ("modifyTimestamp".equals(attribute)) {
        String[] _attributeName = new String[1];
        _attributeName[0] = attribute;
        _atts = ctx.getAttributes(DN, _attributeName);
      } else {
        _atts = ctx.getAttributes(DN);
        if (_atts == null) {
          throw new LDAPException("entry not found [" + DN + "]");
        }
      }
      Attribute _att = _atts.get(attribute);
      if (_att == null) {
        throw new LDAPException("attribute [" + attribute + "] not found in entry");
      }

      @SuppressWarnings("unchecked")
      NamingEnumeration<Object> _ne = (NamingEnumeration<Object>) _att.getAll();
      while (_ne.hasMore()) {
        _values.add(_ne.next());
      }
      return _values;
    } catch (NullPointerException e) {
      _log.log(java.util.logging.Level.ALL, "getEntryAttribute() null pointer");
      throw new LDAPException("get entry attribute null pointer");
    } catch (NamingException e) {
      _log.log(java.util.logging.Level.ALL, "getEntryAttribute() - " + e.getMessage());
      throw new LDAPException(e.getMessage());
    } finally {
      connection.disconnect();
    }
  }
Beispiel #14
0
 private void getAllAttributes() {
   System.out.println("Inside getAllAttributes");
   Attributes attrs = null;
   try {
     DirContext ctx = LDAPConstants.getLdapContext();
     attrs = ctx.getAttributes("");
     NamingEnumeration enm = attrs.getAll();
     while (enm.hasMore()) {
       System.out.println(enm.next());
     }
   } catch (NamingException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
   }
 }
Beispiel #15
0
 // 创建一个用于测试的用户组(当用户组不存在时创建)
 private void createGroup() throws NamingException {
   try {
     Attributes attr = ctx.getAttributes(BASE_DN);
   } catch (NamingException ne) {
     Attribute objclass = new BasicAttribute("objectclass");
     objclass.add("top");
     objclass.add("groupofuniquenames");
     Attribute cn = new BasicAttribute("cn", "student");
     Attributes attrs = new BasicAttributes();
     attrs.put(objclass);
     attrs.put(cn);
     ctx.bind(BASE_DN, null, attrs);
     System.out.println("Group created.n");
   }
 }
Beispiel #16
0
 /**
  * Send anonymous email. Note that although we could give any address as from address, (for
  * example: <b>'[email protected]' is valid</b>), the from of MailMessage should always be the correct format
  * of email address(for example the <b>'aaaa' is invalid</b>). Otherwise an exception would be
  * thrown say that username is invalid.
  *
  * @param mail The MailMessage object which contains at least all the required attributes to be
  *     sent.
  */
 public static void sendAnonymousEmail(MailMessage mail) {
   String dns = "dns://";
   Hashtable<String, String> env = new Hashtable<String, String>();
   env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory");
   env.put(Context.PROVIDER_URL, dns);
   String[] tos = mail.getTos();
   try {
     DirContext ctx = new InitialDirContext(env);
     for (String to : tos) {
       String domain = to.substring(to.indexOf('@') + 1);
       // Get MX(Mail eXchange) records from DNS
       Attributes attrs = ctx.getAttributes(domain, new String[] {"MX"});
       if (attrs == null || attrs.size() <= 0) {
         throw new java.lang.IllegalStateException(
             "Error: Your DNS server has no Mail eXchange records!");
       }
       @SuppressWarnings("rawtypes")
       NamingEnumeration servers = attrs.getAll();
       String smtpHost = null;
       boolean isSend = false;
       StringBuffer buf = new StringBuffer();
       // try all the mail exchange server to send the email.
       while (servers.hasMore()) {
         Attribute hosts = (Attribute) servers.next();
         for (int i = 0; i < hosts.size(); ++i) {
           // sample: 20 mx2.qq.com
           smtpHost = (String) hosts.get(i);
           // parse the string to get smtpHost. sample: mx2.qq.com
           smtpHost = smtpHost.substring(smtpHost.lastIndexOf(' ') + 1);
           try {
             sendEmail(smtpHost, mail, true);
             isSend = true;
             return;
           } catch (Exception e) {
             LOGGER.error("", e);
             buf.append(e.toString()).append("\r\n");
             continue;
           }
         }
       }
       if (!isSend) {
         throw new java.lang.IllegalStateException("Error: Send email error." + buf.toString());
       }
     }
   } catch (NamingException e) {
     LOGGER.error("", e);
   }
 }
 /**
  * Gets an <code>LDAPDirectoryEntry</code> object that represent an entry on directory. You can
  * provide a list of attributes to be ignored when load the entry data. Look for attribute matches
  * using a map of values
  *
  * @param DN Distinguished Name of the entry
  * @param ignore_attributes You can indicate here a list of attribute to be ignored when load all
  *     entry data. this is useful if you have some big data in some attributes and do you want to
  *     ignore that
  * @param attribute_matches Map with attribute names and values to match
  * @return LDAPDirectoryEntry
  * @exception LDAPException
  */
 public LDAPDirectoryEntry getEntry(
     final String DN,
     final List<String> ignore_attributes,
     final Map<String, String> attribute_matches)
     throws LDAPException {
   LDAPDirectoryEntry _e = null;
   try {
     _e = new LDAPDirectoryEntry(DN);
     DirContext ctx = connection.connect();
     if (ctx == null) {
       throw new LDAPException("directory service not available");
     }
     Attributes atts = ctx.getAttributes(DN);
     if (atts == null) {
       return null;
     }
     @SuppressWarnings("unchecked")
     NamingEnumeration<Attribute> ne = (NamingEnumeration<Attribute>) atts.getAll();
     while (ne.hasMore()) {
       Attribute att = ne.next();
       if (ignore_attributes == null || !ignore_attributes.contains(att.getID())) {
         List<Object> _values = new ArrayList<Object>();
         @SuppressWarnings("unchecked")
         NamingEnumeration<Object> nea = (NamingEnumeration<Object>) att.getAll();
         while (nea.hasMore()) {
           Object _value = nea.next();
           if (attribute_matches == null || !attribute_matches.containsKey(att.getID())) {
             _values.add(_value);
           } else if (attribute_matches.get(att.getID()) != null
               && String.valueOf(_value).contains(attribute_matches.get(att.getID()))) {
             _values.add(_value);
           }
         }
         _e.setAttribute(att.getID(), _values.toArray());
       }
     }
   } catch (NullPointerException e) {
     _log.log(java.util.logging.Level.ALL, "getEntry() null pointer");
     throw new LDAPException("get entry null pointer");
   } catch (NamingException e) {
     _log.log(java.util.logging.Level.ALL, "getEntry() - " + e.getMessage());
     throw new LDAPException(e.getMessage());
   } finally {
     connection.disconnect();
   }
   return _e;
 }
Beispiel #18
0
  /** Test that the partition has been correctly created */
  public void testPartition() throws NamingException {

    // We should be able to read it
    DirContext appRoot = createContext("o=sevenSeas");
    assertNotNull(appRoot);

    // Let's get the entry associated to the top level
    Attributes attributes = appRoot.getAttributes("");
    assertNotNull(attributes);
    assertEquals("sevenseas", attributes.get("o").get());

    Attribute attribute = attributes.get("objectClass");
    assertNotNull(attribute);
    assertTrue(attribute.contains("top"));
    assertTrue(attribute.contains("organization"));
    // Ok, everything is fine
  }
Beispiel #19
0
  /** Parse the URL in the following formats:<br> */
  protected void parseServerURLs() {
    int dbPos = url.indexOf('/');
    if (dbPos == -1) {
      // SHORT FORM
      addHost(getDefaultHost());
      name = url;
    } else {
      name = url.substring(dbPos + 1);
      for (String host : url.substring(0, dbPos).split(ADDRESS_SEPARATOR)) host = addHost(host);
    }

    if (serverURLs.size() == 1
        && OGlobalConfiguration.NETWORK_BINARY_DNS_LOADBALANCING_ENABLED.getValueAsBoolean()) {
      // LOOK FOR LOAD BALANCING DNS TXT RECORD
      final String primaryServer = serverURLs.get(0);

      try {
        final Hashtable<String, String> env = new Hashtable<String, String>();
        env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
        env.put(
            "com.sun.jndi.ldap.connect.timeout",
            OGlobalConfiguration.NETWORK_BINARY_DNS_LOADBALANCING_TIMEOUT.getValueAsString());
        final DirContext ictx = new InitialDirContext(env);
        final String hostName =
            primaryServer.indexOf(":") == -1
                ? primaryServer
                : primaryServer.substring(0, primaryServer.indexOf(":"));
        final Attributes attrs = ictx.getAttributes(hostName, new String[] {"TXT"});
        final Attribute attr = attrs.get("TXT");
        if (attr != null) {
          String configuration = (String) attr.get();
          if (configuration.startsWith(""))
            configuration = configuration.substring(1, configuration.length() - 1);
          if (configuration != null) {
            final String[] parts = configuration.split(" ");
            for (String part : parts) {
              if (part.startsWith("s=")) {
                addHost(part.substring("s=".length()));
              }
            }
          }
        }
      } catch (NamingException e) {
      }
    }
  }
  /**
   * Verify if an entry Distinguished Name already exists on directory
   *
   * @param DN Distinguished Name of the entry
   * @return boolean
   * @exception LDAPException
   */
  public boolean checkEntry(final String DN) throws LDAPException {
    try {
      DirContext ctx = connection.connect();
      if (ctx == null) {
        throw new LDAPException("directory service not available");
      }
      if (ctx.getAttributes(DN) != null) {
        return true;
      }
    } catch (NullPointerException e) {
      _log.log(java.util.logging.Level.ALL, "checkEntry() null pointer");
      throw new LDAPException("add entry null pointer");
    } catch (NamingException e) {
      _log.log(java.util.logging.Level.ALL, "checkEntry() - " + e.getMessage());
      throw new LDAPException(e.getMessage());

    } finally {
      connection.disconnect();
    }
    return false;
  }
Beispiel #21
0
  /**
   * This method retrieves data using LDAP protocol. - CRL from given LDAP url, e.g.
   * ldap://ldap.infonotary.com/dc=identity-ca,dc=infonotary,dc=com
   *
   * @param urlString
   * @return
   */
  private byte[] ldapGet(final String urlString) {

    final Hashtable<String, String> env = new Hashtable<String, String>();
    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    env.put(Context.PROVIDER_URL, urlString);
    try {

      final DirContext ctx = new InitialDirContext(env);
      final Attributes attributes = ctx.getAttributes("");
      final javax.naming.directory.Attribute attribute =
          attributes.get("certificateRevocationList;binary");
      final byte[] ldapBytes = (byte[]) attribute.get();
      if (ldapBytes == null || ldapBytes.length == 0) {
        throw new DSSException("Cannot download CRL from: " + urlString);
      }
      return ldapBytes;
    } catch (Exception e) {
      LOG.warn(e.getMessage(), e);
    }
    return null;
  }
  protected boolean bindUser(DirContext context, String dn, String password)
      throws NamingException {
    boolean isValid = false;

    if (ActiveMQServerLogger.LOGGER.isDebugEnabled()) {
      ActiveMQServerLogger.LOGGER.debug("Binding the user.");
    }
    context.addToEnvironment(Context.SECURITY_PRINCIPAL, dn);
    context.addToEnvironment(Context.SECURITY_CREDENTIALS, password);
    try {
      context.getAttributes("", null);
      isValid = true;
      if (ActiveMQServerLogger.LOGGER.isDebugEnabled()) {
        ActiveMQServerLogger.LOGGER.debug("User " + dn + " successfully bound.");
      }
    } catch (AuthenticationException e) {
      isValid = false;
      if (ActiveMQServerLogger.LOGGER.isDebugEnabled()) {
        ActiveMQServerLogger.LOGGER.debug("Authentication failed for dn=" + dn);
      }
    }

    if (isLoginPropertySet(CONNECTION_USERNAME)) {
      context.addToEnvironment(
          Context.SECURITY_PRINCIPAL, getLDAPPropertyValue(CONNECTION_USERNAME));
    } else {
      context.removeFromEnvironment(Context.SECURITY_PRINCIPAL);
    }
    if (isLoginPropertySet(CONNECTION_PASSWORD)) {
      context.addToEnvironment(
          Context.SECURITY_CREDENTIALS, getLDAPPropertyValue(CONNECTION_PASSWORD));
    } else {
      context.removeFromEnvironment(Context.SECURITY_CREDENTIALS);
    }

    return isValid;
  }
    /**
     * Use DNS and obtains the LDAP servers that we should try.
     *
     * @param preferredServers If non-null, these servers are reported instead of doing the
     *     discovery. In previous versions, this was simply added on top of the auto-discovered
     *     list, but this option is useful when you have many domain controllers (because a single
     *     mistyped password can cause an authentication attempt with every listed server, which can
     *     lock the user out!) This also puts this feature in alignment with {@link
     *     #DOMAIN_CONTROLLERS}, which seems to indicate that there are users who prefer this
     *     behaviour.
     * @return A list with at least one item.
     */
    public List<SocketInfo> obtainLDAPServer(
        DirContext ictx, String domainName, String site, String preferredServers)
        throws NamingException {
      List<SocketInfo> result = new ArrayList<SocketInfo>();
      if (preferredServers == null) preferredServers = DOMAIN_CONTROLLERS;

      if (preferredServers != null) {
        for (String token : preferredServers.split(",")) {
          result.add(new SocketInfo(token.trim()));
        }
        return result;
      }

      String ldapServer = null;
      Attribute a = null;
      NamingException failure = null;

      // try global catalog if it exists first, then the particular domain
      for (String candidate : CANDIDATES) {
        ldapServer = candidate + (site != null ? site + "._sites." : "") + domainName;
        LOGGER.fine("Attempting to resolve " + ldapServer + " to SRV record");
        try {
          Attributes attributes = ictx.getAttributes(ldapServer, new String[] {"SRV"});
          a = attributes.get("SRV");
          if (a != null) break;
        } catch (NamingException e) {
          // failed retrieval. try next option.
          failure = e;
        }
      }

      if (a != null) {
        // discover servers
        class PrioritizedSocketInfo implements Comparable<PrioritizedSocketInfo> {
          SocketInfo socket;
          int priority;

          PrioritizedSocketInfo(SocketInfo socket, int priority) {
            this.socket = socket;
            this.priority = priority;
          }

          public int compareTo(PrioritizedSocketInfo that) {
            return that.priority - this.priority; // sort them so that bigger priority comes first
          }
        }
        List<PrioritizedSocketInfo> plist = new ArrayList<PrioritizedSocketInfo>();
        for (NamingEnumeration ne = a.getAll(); ne.hasMoreElements(); ) {
          String record = ne.next().toString();
          LOGGER.fine("SRV record found: " + record);
          String[] fields = record.split(" ");
          // fields[1]: weight
          // fields[2]: port
          // fields[3]: target host name

          String hostName = fields[3];
          // cut off trailing ".". JENKINS-2647
          if (hostName.endsWith(".")) hostName = hostName.substring(0, hostName.length() - 1);
          int port = Integer.parseInt(fields[2]);
          if (FORCE_LDAPS) {
            // map to LDAPS ports. I don't think there's any SRV records specifically for LDAPS.
            // I think Microsoft considers LDAP+TLS the way to go, or else there should have been
            // separate SRV entries.
            if (port == 389) port = 686;
            if (port == 3268) port = 3269;
          }
          int p = Integer.parseInt(fields[0]);
          plist.add(new PrioritizedSocketInfo(new SocketInfo(hostName, port), p));
        }
        Collections.sort(plist);
        for (PrioritizedSocketInfo psi : plist) result.add(psi.socket);
      }

      if (result.isEmpty()) {
        NamingException x = new NamingException("No SRV record found for " + ldapServer);
        if (failure != null) x.initCause(failure);
        throw x;
      }

      LOGGER.fine(ldapServer + " resolved to " + result);
      return result;
    }
Beispiel #24
0
 // 查找用户
 private Attributes findUser(String uid) throws NamingException {
   return ctx.getAttributes("uid=" + uid + "," + BASE_DN);
 }
Beispiel #25
0
 /**
  * List all the attributes of an LDAP node.
  *
  * @param root The root DirContext.
  * @param dn The DN of the node, relative to the root DirContext.
  */
 public static void listAttributes(DirContext root, String dn) throws NamingException {
   final Attributes attrs = root.getAttributes(dn);
   System.out.println("dn: " + dn);
   System.out.println("attributes: " + attrs);
 }
  /**
   * Resolves all the groups that the user is in.
   *
   * <p>We now use <a
   * href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms680275(v=vs.85).aspx">tokenGroups</a>
   * attribute, which is a computed attribute that lists all the SIDs of the groups that the user is
   * directly/indirectly in. We then use that to retrieve all the groups in one query and resolve
   * their canonical names.
   *
   * @param userDN User's distinguished name.
   * @param context Used for making queries.
   */
  private Set<GrantedAuthority> resolveGroups(String domainDN, String userDN, DirContext context)
      throws NamingException {
    LOGGER.finer("Looking up group of " + userDN);
    Attributes id = context.getAttributes(userDN, new String[] {"tokenGroups", "memberOf", "CN"});
    Attribute tga = id.get("tokenGroups");
    if (tga == null) { // see JENKINS-11644. still trying to figure out when this happens
      LOGGER.warning("Failed to retrieve tokenGroups for " + userDN);
      HashSet<GrantedAuthority> r = new HashSet<GrantedAuthority>();
      r.add(new GrantedAuthorityImpl("unable-to-retrieve-tokenGroups"));
      return r;
    }

    // build up the query to retrieve all the groups
    StringBuilder query = new StringBuilder("(|");
    List<byte[]> sids = new ArrayList<byte[]>();

    NamingEnumeration<?> tokenGroups = tga.getAll();
    while (tokenGroups.hasMore()) {
      byte[] gsid = (byte[]) tokenGroups.next();
      query.append("(objectSid={" + sids.size() + "})");
      sids.add(gsid);
    }
    tokenGroups.close();

    query.append(")");

    Set<GrantedAuthority> groups = new HashSet<GrantedAuthority>();

    NamingEnumeration<SearchResult> renum =
        new LDAPSearchBuilder(context, domainDN)
            .subTreeScope()
            .returns("cn")
            .search(query.toString(), sids.toArray());
    while (renum.hasMore()) {
      Attributes a = renum.next().getAttributes();
      Attribute cn = a.get("cn");
      if (LOGGER.isLoggable(Level.FINE)) LOGGER.fine(userDN + " is a member of " + cn);
      groups.add(new GrantedAuthorityImpl(cn.get().toString()));
    }
    renum.close();

    {
        /*
            stage 2: use memberOf to find groups that aren't picked up by tokenGroups.
            This includes distribution groups
        */
      LOGGER.fine("Stage 2: looking up via memberOf");

      Stack<Attributes> q = new Stack<Attributes>();
      q.push(id);
      while (!q.isEmpty()) {
        Attributes identity = q.pop();
        LOGGER.finer("Looking up group of " + identity);

        Attribute memberOf = identity.get("memberOf");
        if (memberOf == null) continue;

        for (int i = 0; i < memberOf.size(); i++) {
          try {
            Attributes group =
                context.getAttributes(
                    new LdapName(memberOf.get(i).toString()), new String[] {"CN", "memberOf"});
            Attribute cn = group.get("CN");
            if (cn == null) {
              LOGGER.fine("Failed to obtain CN of " + memberOf.get(i));
              continue;
            }
            if (LOGGER.isLoggable(Level.FINE))
              LOGGER.fine(cn.get() + " is a member of " + memberOf.get(i));

            if (groups.add(new GrantedAuthorityImpl(cn.get().toString()))) {
              q.add(group); // recursively look for groups that this group is a member of.
            }
          } catch (NameNotFoundException e) {
            LOGGER.fine("Failed to obtain CN of " + memberOf.get(i));
          }
        }
      }
    }

    return groups;
  }
    public FormValidation doValidate(
        @QueryParameter(fixEmpty = true) String domain,
        @QueryParameter(fixEmpty = true) String site,
        @QueryParameter(fixEmpty = true) String bindName,
        @QueryParameter(fixEmpty = true) String bindPassword,
        @QueryParameter(fixEmpty = true) String server)
        throws IOException, ServletException, NamingException {
      ClassLoader ccl = Thread.currentThread().getContextClassLoader();
      Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
      try {
        Functions.checkPermission(Hudson.ADMINISTER);
        String n = Util.fixEmptyAndTrim(domain);
        if (n == null) { // no value given yet
          return FormValidation.error("No domain name set");
        }

        Secret password = Secret.fromString(bindPassword);
        if (bindName != null && password == null)
          return FormValidation.error("DN is specified but not password");

        String[] names = n.split(",");
        for (String name : names) {

          if (!name.endsWith(".")) name += '.';

          DirContext ictx;

          // first test the sanity of the domain name itself
          try {
            LOGGER.fine("Attempting to resolve " + name + " to NS record");
            ictx = createDNSLookupContext();
            Attributes attributes = ictx.getAttributes(name, new String[] {"NS"});
            Attribute ns = attributes.get("NS");
            if (ns == null) {
              LOGGER.fine("Attempting to resolve " + name + " to A record");
              attributes = ictx.getAttributes(name, new String[] {"A"});
              Attribute a = attributes.get("A");
              if (a == null) throw new NamingException(name + " doesn't look like a domain name");
            }
            LOGGER.log(Level.FINE, "{0} resolved to {1}", new Object[] {name, ns});
          } catch (NamingException e) {
            LOGGER.log(Level.WARNING, "Failed to resolve " + name + " to A record", e);
            return FormValidation.error(e, name + " doesn't look like a valid domain name");
          }

          // then look for the LDAP server
          List<SocketInfo> servers;
          try {
            servers = obtainLDAPServer(ictx, name, site, server);
          } catch (NamingException e) {
            String msg =
                site == null
                    ? "No LDAP server was found in " + name
                    : "No LDAP server was found in the " + site + " site of " + name;
            LOGGER.log(Level.WARNING, msg, e);
            return FormValidation.error(e, msg);
          }

          if (bindName != null) {
            // make sure the bind actually works
            try {
              DirContext context = bind(bindName, Secret.toString(password), servers);
              try {
                // actually do a search to make sure the credential is valid
                new LDAPSearchBuilder(context, toDC(domain)).searchOne("(objectClass=user)");
              } finally {
                context.close();
              }
            } catch (BadCredentialsException e) {
              return FormValidation.error(e, "Bad bind username or password");
            } catch (javax.naming.AuthenticationException e) {
              return FormValidation.error(e, "Bad bind username or password");
            } catch (Exception e) {
              return FormValidation.error(e, e.getMessage());
            }
          } else {
            // just some connection test
            // try to connect to LDAP port to make sure this machine has LDAP service
            IOException error = null;
            for (SocketInfo si : servers) {
              try {
                si.connect().close();
                break; // looks good
              } catch (IOException e) {
                LOGGER.log(Level.FINE, "Failed to connect to " + si, e);
                error = e;
                // try the next server in the list
              }
            }
            if (error != null) {
              LOGGER.log(Level.WARNING, "Failed to connect to " + servers, error);
              return FormValidation.error(error, "Failed to connect to " + servers);
            }
          }
        }

        // looks good
        return FormValidation.ok("Success");
      } finally {
        Thread.currentThread().setContextClassLoader(ccl);
      }
    }
  /**
   * 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);
  }